mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-07 23:42:21 +02:00
fix(security): avoid SVG title DOM reparsing
Extract strict text-only SVG titles without reparsing model output as DOM, preserving sandboxed SVG rendering and safe accessibility labels.
This commit is contained in:
@@ -61,11 +61,12 @@ const { extractThemeBootstrap } = require('./helpers/theme_bootstrap.cjs');
|
||||
const valid = addMessage('user', 'In the document, edit this specific text (lines 1–2):\n```\nselected\n```\n\nInstruction: **Keep bold** and `code`');
|
||||
const titles = [
|
||||
{ source: '<svg xmlns="http://www.w3.org/2000/svg"><title>Valid & safe</title></svg>', title: 'Valid & safe' },
|
||||
{ source: '<svg><title>Nested <b>bold</b> & text</title></svg>', title: 'Nested bold & text' },
|
||||
{ source: '<svg><title>Numeric <safe> & sound</title></svg>', title: 'Numeric <safe> & sound' },
|
||||
{ source: '<svg><title>Nested <b>bold</b> & text</title></svg>', title: 'Visual explanation' },
|
||||
{ source: '<svg><title>\" onload=\"parent.executed++ <script></title></svg>', title: '\" onload=\"parent.executed++ <script>' },
|
||||
{ source: '<svg><title>Malformed <b>nested</title ></svg>', title: 'Visual explanation' },
|
||||
{ source: '<svg><title><script>parent.executed++</script><b onload="parent.executed++">nested</b></title></svg>', title: 'parent.executed++nested' },
|
||||
{ source: '<svg><title><![CDATA["><img src=x onerror="parent.executed++">]]></title></svg>', title: '"><img src=x onerror="parent.executed++">' },
|
||||
{ source: '<svg><title><script>parent.executed++</script><b onload="parent.executed++">nested</b></title></svg>', title: 'Visual explanation' },
|
||||
{ source: '<svg><title><![CDATA["><img src=x onerror="parent.executed++">]]></title></svg>', title: 'Visual explanation' },
|
||||
{ source: '<svg><title></title><img src=x onerror="parent.executed++"></svg>', title: 'Visual explanation' },
|
||||
{ source: '<svg><title> </title></svg>', title: 'Visual explanation' },
|
||||
{ source: '<svg><text>No title</text></svg>', title: 'Visual explanation' },
|
||||
|
||||
@@ -7,15 +7,17 @@ from tests.helpers.document_source import document_source
|
||||
_REPO = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
def test_svg_title_extraction_uses_xml_text_without_html_assignment():
|
||||
def test_svg_title_extraction_never_reparses_model_output_as_dom():
|
||||
src = (_REPO / "static" / "js" / "markdown.js").read_text(encoding="utf-8")
|
||||
render = src.split("function renderSvgSandbox(source)", 1)[1].split(
|
||||
"function replaceRawSvgBlocks", 1
|
||||
)[0]
|
||||
assert "innerHTML" not in render
|
||||
assert "parseFromString(cleaned, 'image/svg+xml')" in render
|
||||
assert "textContent" in render
|
||||
assert "parsererror" in render
|
||||
assert "DOMParser" not in render
|
||||
assert "parseFromString" not in render
|
||||
assert "decodeSvgTitleEntities" in render
|
||||
assert "([^<>]*)" in render
|
||||
assert "Visual explanation" in render
|
||||
|
||||
|
||||
def test_markdown_raw_html_sanitizer_checks_url_attr_edge_cases():
|
||||
|
||||
Reference in New Issue
Block a user