"""Unit tests for the shared HTML output-sanitization policy (GHSA-v5mq-3xhg-98m9)."""
import pytest
from unstructured.documents.html_sanitization import (
ALLOWED_URL_SCHEMES,
is_event_handler_attribute,
is_safe_tag,
is_safe_url,
sanitize_attributes,
sanitize_html_fragment,
sanitize_style_attribute,
)
class DescribeIsSafeUrl:
@pytest.mark.parametrize(
"url",
[
"http://example.com",
"https://example.com/path?q=1",
"mailto:user@example.com",
"tel:+15551234",
"/relative/path",
"relative/path",
"#anchor",
"?query=only",
],
)
def it_allows_safe_urls(self, url: str):
assert is_safe_url(url) is True
@pytest.mark.parametrize(
"url",
[
"javascript:alert(1)",
"JaVaScRiPt:alert(1)",
" javascript:alert(1)",
"java\tscript:alert(1)",
"java\nscript:alert(1)",
"vbscript:msgbox(1)",
"data:text/html,",
"data:application/javascript,alert(1)",
"file:///etc/passwd",
],
)
def it_rejects_dangerous_urls(self, url: str):
assert is_safe_url(url) is False
def it_only_permits_raster_image_data_uris_on_img_src(self):
# -- data: is in the scheme allowlist but narrowed to raster img[src] so
# -- base64 images survive while script-executable data URIs do not --
assert "data" in ALLOWED_URL_SCHEMES
assert (
is_safe_url(
"data:image/gif;base64,R0lGOD",
tag_name="img",
attribute_name="src",
)
is True
)
assert (
is_safe_url(
"data:image/svg+xml;base64,PHN2Zz4=",
tag_name="img",
attribute_name="src",
)
is False
)
assert (
is_safe_url(
"data:image/png;base64,iVBORw0KGgo=",
tag_name="a",
attribute_name="href",
)
is False
)
assert (
is_safe_url(
"data:text/html;base64,PHNjcmlwdD4=",
tag_name="img",
attribute_name="src",
)
is False
)
class DescribeIsEventHandlerAttribute:
@pytest.mark.parametrize("name", ["onerror", "onload", "onmouseover", "ONCLICK", " onfocus"])
def it_detects_event_handlers(self, name: str):
assert is_event_handler_attribute(name) is True
@pytest.mark.parametrize("name", ["class", "href", "id", "data-src", "title"])
def it_ignores_non_event_handlers(self, name: str):
assert is_event_handler_attribute(name) is False
class DescribeIsSafeTag:
@pytest.mark.parametrize("tag", ["div", "p", "a", "img", "table", "TD", "svg"])
def it_allows_known_tags(self, tag: str):
assert is_safe_tag(tag) is True
@pytest.mark.parametrize("tag", ["script", "iframe", "object", "embed", "", None])
def it_rejects_unknown_tags(self, tag):
assert is_safe_tag(tag) is False
class DescribeSanitizeAttributes:
def it_drops_event_handler_attributes(self):
result = sanitize_attributes(
{"onerror": "alert(1)", "onmouseover": "x", "class": "Foo"},
tag_name="p",
)
assert result == {"class": "Foo"}
def it_drops_url_attributes_with_unsafe_schemes(self):
result = sanitize_attributes({"href": "javascript:alert(1)", "id": "x"}, tag_name="a")
assert result == {"id": "x"}
def it_keeps_url_attributes_with_safe_schemes(self):
link_result = sanitize_attributes({"href": "https://example.com"}, tag_name="a")
image_result = sanitize_attributes({"src": "/img.png"}, tag_name="img")
assert link_result == {"href": "https://example.com"}
assert image_result == {"src": "/img.png"}
def it_keeps_raster_data_image_uris_on_img_src(self):
result = sanitize_attributes({"src": "data:image/png;base64,AAAA"}, tag_name="img")
assert result == {"src": "data:image/png;base64,AAAA"}
def it_drops_data_image_uris_outside_img_src(self):
result = sanitize_attributes({"href": "data:image/png;base64,AAAA"}, tag_name="a")
assert result == {}
def it_drops_svg_data_image_uris(self):
result = sanitize_attributes({"src": "data:image/svg+xml;base64,PHN2Zz4="}, tag_name="img")
assert result == {}
def it_drops_malformed_attribute_names(self):
# -- a name that isn't a valid HTML attribute name can't be emitted safely --
result = sanitize_attributes({'x">