Skip to content

Commit 12fa966

Browse files
committed
Cleaner: Prevent "@import" from re-occurring in the CSS after replacements, e.g. "@@importimport".
Reported as GHSL-2021-1037
1 parent 24a4599 commit 12fa966

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

Diff for: src/lxml/html/clean.py

+2
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,8 @@ def _has_sneaky_javascript(self, style):
541541
return True
542542
if 'expression(' in style:
543543
return True
544+
if '@import' in style:
545+
return True
544546
if '</noscript' in style:
545547
# e.g. '<noscript><style><a title="</noscript><img src=x onerror=alert(1)>">'
546548
return True

Diff for: src/lxml/html/tests/test_clean.py

+20
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,26 @@ def test_sneaky_js_in_math_style(self):
123123
b'<math><style>/* deleted */</style></math>',
124124
lxml.html.tostring(clean_html(s)))
125125

126+
def test_sneaky_import_in_style(self):
127+
# Prevent "@@importimport" -> "@import" replacement.
128+
style_codes = [
129+
"@@importimport(extstyle.css)",
130+
"@ @ import import(extstyle.css)",
131+
"@ @ importimport(extstyle.css)",
132+
"@@ import import(extstyle.css)",
133+
"@ @import import(extstyle.css)",
134+
"@@importimport()",
135+
]
136+
for style_code in style_codes:
137+
html = '<style>%s</style>' % style_code
138+
s = lxml.html.fragment_fromstring(html)
139+
140+
cleaned = lxml.html.tostring(clean_html(s))
141+
self.assertEqual(
142+
b'<style>/* deleted */</style>',
143+
cleaned,
144+
"%s -> %s" % (style_code, cleaned))
145+
126146
def test_formaction_attribute_in_button_input(self):
127147
# The formaction attribute overrides the form's action and should be
128148
# treated as a malicious link attribute

0 commit comments

Comments
 (0)