some initial commits, starting what is going to be probably rewritten in C or rust later. idk. its getting late.

This commit is contained in:
2026-04-17 23:10:59 +02:00
parent a024ba45d7
commit bbefb1749d
4 changed files with 136 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
# saningi-html todo
## Current:
- [x] basic cli argparsing working (stdin -> sanizization -> stdout)
- [x] Modes implemented:
- strict
- loose
- passthrough
- [x] profiles in a seperate .py file
## To implement:
things not yet implemented in the program
### url filtering:
- [ ] block external URL in strict mode (eg a link with href to some porn site or something)
- [ ] allow relative paths:
- eg "/path/to/my/awesome/post.html"
- [ ] apply to any of these:
- a
- img
- link href
- [ ] add custom attribute filter function
---
### Expland strict mode:
- [ ] Allow these:
- html, head, body
- title
- meta (with restrictions)
- link (for css only)
- table, tr, td, th
- any of crucuial html tags
- [ ] restrict metas (allow):
- allow only charset, name, content
- [ ] restrict metas (dont allow):
- base
- meta http-equiv
---
### passthrough safety
- [ ] add stderr warning for user
---
### Add some logging:
- [ ] debugging with --debug
- [ ] print what was removed, to stderr
### Config files:
- [ ] allow custom JSON/YAML/yadayadayada configurations
- pass in through CLI with flag --config "file.idk"
BIN
View File
Binary file not shown.
+47
View File
@@ -0,0 +1,47 @@
import sys
import argparse
import bleach
from profiles import STRICT, LOOSE
PROFILES = {
"strict": STRICT,
"loose": LOOSE,
}
def sanitize(html : str, mode : str) -> str:
# this should be used with caution! it is for trusted
# individuals only
if mode == "passthrough":
return html
config = PROFILES.get(mode)
if not config:
raise ValueError(f"Unknown mode! : {mode}")
return bleach.clean(
html,
tags=config["tags"],
attributes=config["attributes"],
protocols=config["protocols"],
strip=config["strip"],
)
def entry():
parser = argparse.ArgumentParser(description="saningi-html sanitizer")
parser.add_argument(
"--mode",
choices=["strict","loose","passthrough"],
default="strict",
help="Strictness of Tags or HTML"
)
args = parser.parse_args()
raw_html = sys.stdin.read()
clean_html = sanitize(raw_html, args.mode)
print(clean_html)
if __name__ == "__main__":
entry()
+35
View File
@@ -0,0 +1,35 @@
#
# src/profiles.py
# AGPL-3 - saningi-html
#
# presets for sanitization of HTML
#
STRICT = {
"tags" : [
"p", "b", "i", "u", "em", "strong",
"ul", "ol", "li",
"br", "hr",
"h1", "h2", "h3", "h4", "h5", "h6"
],
"attributes": {},
"protocols": [],
"strip": True,
}
# like my ass :3
LOOSE = {
"tags": [
"p", "b", "i", "u", "em", "strong",
"ul", "ol", "li",
"br", "hr", "span", "div",
"a", "img",
"h1", "h2", "h3", "h4", "h5", "h6"
],
"attributes": {
"a": ["href", "title"],
"img": {"src", "alt", "style", "loading"}
},
"protocols": ["http", "https"],
"strip": True,
}