Compare commits

..

1 commit

Author SHA1 Message Date
Mikolaj Izdebski
1244f63618 Fix mXSS vulnerability due to the use of improper parser
Resolves: CVE-2020-27783
2020-12-18 16:20:25 +01:00
11 changed files with 1636 additions and 1784 deletions

View file

@ -1 +0,0 @@
1

20
.gitignore vendored
View file

@ -53,23 +53,3 @@ lxml-2.2.7.tar.gz.asc
/lxml-4.2.5.tgz
/lxml-4.4.0.tgz
/lxml-4.4.1.tgz
/lxml-4.5.1.tgz
/lxml-4.6.2.tar.gz
/lxml-4.6.3.tar.gz
/lxml-4.7.1.tar.gz
/lxml-4.9.1.tar.gz
/lxml-4.9.2.tar.gz
/lxml-4.9.2-no-isoschematron.tar.gz
/lxml-4.9.2-no-isoschematron-rng.tar.gz
/lxml-4.9.3-no-isoschematron-rng.tar.gz
/lxml-4.9.4-no-isoschematron-rng.tar.gz
/lxml-5.1.0-no-isoschematron-rng.tar.gz
/lxml-5.2.0-no-isoschematron-rng.tar.gz
/lxml-5.2.1-no-isoschematron-rng.tar.gz
/lxml-5.3.0-no-isoschematron-rng.tar.gz
/lxml-5.3.1-no-isoschematron-rng.tar.gz
/lxml-5.3.2-no-isoschematron-rng.tar.gz
/lxml-5.4.0-no-isoschematron-rng.tar.gz
/lxml-6.0.0-no-isoschematron-rng.tar.gz
/lxml-6.0.1-no-isoschematron-rng.tar.gz
/lxml-6.0.2-no-isoschematron-rng.tar.gz

View file

@ -0,0 +1,74 @@
From b49ffd817ecce80a5d0d6a541c58b92ebb51656b Mon Sep 17 00:00:00 2001
From: Mikolaj Izdebski <mizdebsk@redhat.com>
Date: Fri, 18 Dec 2020 16:13:04 +0100
Subject: [PATCH] Fix CVE-2020-27783: mXSS due to the use of improper parser
Backported from upstream commits 89e7aad6e7ff9ecd88678ff25f885988b184b26e
and a105ab8dc262ec6735977c25c13f0bdfcdec72a7
---
src/lxml/html/clean.py | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/src/lxml/html/clean.py b/src/lxml/html/clean.py
index aa9fc57f..15298b5d 100644
--- a/src/lxml/html/clean.py
+++ b/src/lxml/html/clean.py
@@ -61,12 +61,15 @@ __all__ = ['clean_html', 'clean', 'Cleaner', 'autolink', 'autolink_html',
# This is an IE-specific construct you can have in a stylesheet to
# run some Javascript:
-_css_javascript_re = re.compile(
- r'expression\s*\(.*?\)', re.S|re.I)
+_replace_css_javascript = re.compile(
+ r'expression\s*\(.*?\)', re.S|re.I).sub
# Do I have to worry about @\nimport?
-_css_import_re = re.compile(
- r'@\s*import', re.I)
+_replace_css_import = re.compile(
+ r'@\s*import', re.I).sub
+
+_looks_like_tag_content = re.compile(
+ r'</?[a-zA-Z]+|\son[a-zA-Z]+\s*=', re.ASCII).search
# All kinds of schemes besides just javascript: that can cause
# execution:
@@ -292,8 +295,8 @@ class Cleaner(object):
if not self.inline_style:
for el in _find_styled_elements(doc):
old = el.get('style')
- new = _css_javascript_re.sub('', old)
- new = _css_import_re.sub('', new)
+ new = _replace_css_javascript('', old)
+ new = _replace_css_import('', new)
if self._has_sneaky_javascript(new):
# Something tricky is going on...
del el.attrib['style']
@@ -305,9 +308,9 @@ class Cleaner(object):
el.drop_tree()
continue
old = el.text or ''
- new = _css_javascript_re.sub('', old)
+ new = _replace_css_javascript('', old)
# The imported CSS can do anything; we just can't allow:
- new = _css_import_re.sub('', old)
+ new = _replace_css_import('', new)
if self._has_sneaky_javascript(new):
# Something tricky is going on...
el.text = '/* deleted */'
@@ -509,6 +512,12 @@ class Cleaner(object):
return True
if 'expression(' in style:
return True
+ if '</noscript' in style:
+ # e.g. '<noscript><style><a title="</noscript><img src=x onerror=alert(1)>">'
+ return True
+ if _looks_like_tag_content(style):
+ # e.g. '<math><style><img src=x onerror=alert(1)></style></math>'
+ return True
return False
def clean_html(self, html):
--
2.26.2

1642
changelog

File diff suppressed because it is too large Load diff

1
ci.fmf
View file

@ -1 +0,0 @@
resultsdb-testcase: separate

View file

@ -1,8 +0,0 @@
--- !Policy
product_versions:
- fedora-*
decision_contexts:
- bodhi_update_push_testing
- bodhi_update_push_stable
rules:
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/smoke.functional}

View file

@ -1,28 +0,0 @@
#! /bin/bash -ex
# Download a release of lxml (if missing) and remove the isoschematron module from it
version=$1
if [ -z "${version}" ]; then
echo "Usage: $0 VERSION" >& 2
echo "" >& 2
echo "example: $0 4.9.2" >& 2
exit 1
fi
versionedname=lxml-${version}
orig_archive=${versionedname}.tar.gz
new_archive=${versionedname}-no-isoschematron-rng.tar.gz
if [ ! -e ${orig_archive} ]; then
wget -N https://files.pythonhosted.org/packages/source/l/lxml/${orig_archive}
fi
deleted_directory=lxml-${version}/src/lxml/isoschematron/resources/rng
# tar --delete does not operate on compressed archives, so do
# gz decompression explicitly
gzip --decompress ${orig_archive}
tar -v --delete -f ${orig_archive//.gz} ${deleted_directory}
gzip -cf ${orig_archive//.gz} > ${new_archive}

View file

@ -1,7 +0,0 @@
import lxml.etree as et
s = '<foo><bar baz="xyzzy">a<![CDATA[b]]>c</bar></foo>'
x = et.fromstring(s)
t = x.find('bar').text
print(t)
if t != 'abc':
raise Exception()

View file

@ -1,12 +0,0 @@
summary: Basic smoke test
discover:
how: shell
tests:
- name: /smoke/import-python-module
test: |
python3 -c 'import importlib as il; print(il.import_module("lxml"))'
- name: /smoke/etree-fromstring
test: |
python3 plans/etree-fromstring.py
execute:
how: tmt

File diff suppressed because it is too large Load diff

View file

@ -1 +1 @@
SHA512 (lxml-6.0.2-no-isoschematron-rng.tar.gz) = dc89f75c3a3c828a46bcb2eefbebe8f98ce8072b9fb66f8ef81edbf2babed74e4c54e26392603319d60ab3bfab6a4795eedc85b28efba815797d43d53aae4060
SHA512 (lxml-4.4.1.tgz) = 3f11469290868f5bd30631020ac170c40da7348853609edf6fc6b00437b053fd774e0dfc6e711703ac5d05398dfa1f31e59a185935c3dc8ef0e1914a518bd049