Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix XXE vulnerability for mathml parser
  • Loading branch information
sylee957 committed Apr 2, 2023
1 parent 93080e5 commit e2734be
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/runtests.yml
Expand Up @@ -199,7 +199,7 @@ jobs:

# dependencies to install in all Python versions:
- run: pip install mpmath numpy numexpr matplotlib ipython cython scipy \
aesara wurlitzer autowrap pytest \
aesara wurlitzer autowrap lxml pytest \
'antlr4-python3-runtime==4.11.*'

# Not available in pypy or cpython 3.11 (yet).
Expand Down
31 changes: 23 additions & 8 deletions sympy/utilities/mathml/__init__.py
Expand Up @@ -20,23 +20,35 @@ def add_mathml_headers(s):

@doctest_depends_on(modules=('lxml',))
def apply_xsl(mml, xsl):
"""Apply a xsl to a MathML string
@param mml: a string with MathML code
@param xsl: a string representing a path to a xsl (xml stylesheet)
file. This file name is relative to the PYTHONPATH
"""Apply a xsl to a MathML string.
Parameters
==========
mml
A string with MathML code.
xsl
A string representing a path to a xsl (xml stylesheet) file.
This file name is relative to the PYTHONPATH.
Examples
========
>>> from sympy.utilities.mathml import apply_xsl
>>> xsl = 'mathml/data/simple_mmlctop.xsl'
>>> mml = '<apply> <plus/> <ci>a</ci> <ci>b</ci> </apply>'
>>> res = apply_xsl(mml,xsl)
>>> ''.join(res.splitlines())
'<?xml version="1.0"?><mrow xmlns="http://www.w3.org/1998/Math/MathML"> <mi>a</mi> <mo> + </mo> <mi>b</mi></mrow>'
"""
from lxml import etree
s = etree.XML(get_resource(xsl).read())
transform = etree.XSLT(s)
doc = etree.XML(mml)

parser = etree.XMLParser(resolve_entities=False)
ac = etree.XSLTAccessControl.DENY_ALL

s = etree.XML(get_resource(xsl).read(), parser=parser)
transform = etree.XSLT(s, access_control=ac)
doc = etree.XML(mml, parser=parser)
result = transform(doc)
s = str(result)
return s
Expand All @@ -48,6 +60,9 @@ def c2p(mml, simple=False):
in one document in MathML presentation, more suitable for printing, and more
widely accepted
Examples
========
>>> from sympy.utilities.mathml import c2p
>>> mml = '<apply> <exp/> <cn>2</cn> </apply>'
>>> c2p(mml,simple=True) != c2p(mml,simple=False)
Expand Down
1 change: 1 addition & 0 deletions sympy/utilities/tests/sensitive.txt
@@ -0,0 +1 @@
USERNAME, PASSWORD
33 changes: 33 additions & 0 deletions sympy/utilities/tests/test_mathml.py
@@ -0,0 +1,33 @@
import os
from textwrap import dedent
from sympy.external import import_module
from sympy.testing.pytest import skip
from sympy.utilities.mathml import apply_xsl



lxml = import_module('lxml')

path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'sensitive.txt'))


def test_xxe():
assert os.path.isfile(path)
if not lxml:
skip("lxml not installed.")

mml = dedent(
rf"""
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file://{path}"> ]>
<userInfo>
<firstName>John</firstName>
<lastName>&ent;</lastName>
</userInfo>
"""
)
xsl = 'mathml/data/simple_mmlctop.xsl'

res = apply_xsl(mml, xsl)
assert res == \
'<?xml version="1.0"?>\n<userInfo>\n<firstName>John</firstName>\n<lastName/>\n</userInfo>\n'

0 comments on commit e2734be

Please sign in to comment.