From bbefb1749dd70d3174d1fea8ea4c4b541155ee0e Mon Sep 17 00:00:00 2001 From: rattatwinko Date: Fri, 17 Apr 2026 23:10:59 +0200 Subject: [PATCH] some initial commits, starting what is going to be probably rewritten in C or rust later. idk. its getting late. --- TODO.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | Bin 0 -> 74 bytes src/main.py | 47 +++++++++++++++++++++++++++++++++++++++++ src/profiles.py | 35 ++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 TODO.md create mode 100644 requirements.txt create mode 100644 src/main.py create mode 100644 src/profiles.py diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..8deb44f --- /dev/null +++ b/TODO.md @@ -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" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..2fe7495d7a83dfa37393aaec32672c0d70f35159 GIT binary patch literal 74 zcmezWFNqv M0I13ohz-Fi0WS~?UH||9 literal 0 HcmV?d00001 diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..25cd988 --- /dev/null +++ b/src/main.py @@ -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() \ No newline at end of file diff --git a/src/profiles.py b/src/profiles.py new file mode 100644 index 0000000..1c15be7 --- /dev/null +++ b/src/profiles.py @@ -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, +}