From 72b5f2f0ddfd268382ed12b7c617c6562be8f40e Mon Sep 17 00:00:00 2001 From: sirdave73 Date: Fri, 4 Sep 2026 02:25:07 -0400 Subject: [PATCH] C1+C3 review findings: streaming decompression-bomb guard + stored-XSS stripping C1 (decompression bomb): wire the shared common._copy_stream_with_cap into both zip-extraction paths. app.py._safe_extract_zip now streams each EPUB member with a WRITTEN-byte counter (app.py:456) instead of an unbounded copyfileobj, so a member that inflates a small header into a huge stream is stopped mid-write. pandoc_converter._validate_office_zip now streams every member's decompressed bytes through the same guard (pandoc_converter.py:134) before pandoc reads them. C3 (stored XSS): common.html_to_pdf_bytes now strips stored-XSS vectors via common._strip_scripts (common.py:320) BEFORE WeasyPrint renders, so every non-pandoc render path (html, svg, epub, md, csv, xml) neutralizes " + "" + 'JS_LINK' + 'VB_LINK' + ) + out = C._strip_scripts(html) + assert "SCRIPT_BODY" not in out + assert "IFRAME_BODY" not in out + assert "EVIL_ATTR()" not in out + assert "EVIL_JS()" not in out + assert "EVIL_VB()" not in out + assert "onmouseover" not in out.lower() + assert "javascript:" not in out.lower() + assert "vbscript:" not in out.lower() + + +def test_strip_scripts_preserves_visible_and_safe_urls(): + """_strip_scripts leaves visible text and safe data:/https: references intact. + Satisfies: C3 + """ + html = ( + "

VISIBLE_TEXT

" + 'local>SAFE_LINK' + ) + out = C._strip_scripts(html) + assert "VISIBLE_TEXT" in out + assert "SAFE_LINK" in out + assert "https://example.com/ok" in out + assert "data:image/png;base64," in out + + +def test_c3_html_guard_wired_job_done_and_content_preserved(client): + """An .html upload with " + "
VISIBLE_MAIN_TEXT
" + 'LINK' + "

SECOND_VISIBLE

" + "" + ) + job = _upload(client, html, "xss.html") + assert job["status"] == "done", job + full = pdf_text(download_bytes(client, job["filename"])) + # Guard must not blank the document: visible content still renders. + assert "VISIBLE_MAIN_TEXT" in full + assert "SECOND_VISIBLE" in full + # Guarded vectors must not be reachable in the rendered document. + assert "SCRIPT_MARKER_TEXT" not in full + assert "EVIL_MARKER" not in full + assert "EVIL_LINK" not in full + + +def test_c3_svg_guard_wired_job_done(client): + """An .svg upload with a " + 'SVG_VISIBLE_TEXT' + "" + ) + job = _upload(client, svg, "xss.svg") assert job["status"] == "done", job \ No newline at end of file