Commits

Christian Heimes committed d848c0a

xmlrpclib's ExpatParser needs protection, too

Comments (0)

Files changed (3)

 
 *Release date: ??-Feb-2013*
 
-- Renamed ExternalEntitiesForbidden to ExternalReferenceForbidden
-- Renamed defusedxml.lxml.check_dtd() to check_docinfo()
-- Unified argument names in callbacks
-- Added arguments and formatted representation to exceptions
+- Rename ExternalEntitiesForbidden to ExternalReferenceForbidden
+- Rename defusedxml.lxml.check_dtd() to check_docinfo()
+- Unify argument names in callbacks
+- Add arguments and formatted representation to exceptions
+- Add forbid_external argument to all functions and classs
 - More tests
+- LOTS of documentation
+- Add example code for other languages (Ruby, Perl, PHP) and parsers (Genshi)
 
 defusedxml 0.1
 --------------
 ====================
 
 .. csv-table::
-   :header: "kind", "sax", "etree", "minidom", "pulldom", "lxml", "genshi"
-   :widths: 24, 8, 8, 8, 8, 8, 8
+   :header: "kind", "sax", "etree", "minidom", "pulldom", "xmlrpc", "lxml", "genshi"
+   :widths: 24, 7, 8, 8, 7, 8, 8, 8
+   :stub-columns: 0
 
-   "billion laughs", "True", "True", "True", "True", "False (1)", "False (5)"
-   "quadratic blowup", "True", "True", "True", "True", "True", "False (5)"
-   "external entity expansion (remote)", "True", "False (3)", "False (4)", "True", "False (1)", "False (5)"
-   "external entity expansion (local file)", "True", "False (3)", "False (4)", "True", "True", "False (5)"
-   "DTD retrieval", "True", "False", "False", "True", "False (1)", "False"
-   "gzip bomb", "False", "False", "False", "False", "partly (2)", "False"
-   "xpath support", "False", "False", "False", "False", "True", "False"
-   "xsl(t) support", "False", "False", "False", "False", "True", "False"
-   "xinclude support", "False", "True (6)", "False", "False", "True (6)", "True"
-   "C library", "expat", "expat", "expat", "expat", "libxml2", "expat"
+   "billion laughs", "**True**", "**True**", "**True**", "**True**", "**True**", "False (1)", "False (5)"
+   "quadratic blowup", "**True**", "**True**", "**True**", "**True**", "**True**", "**True**", "False (5)"
+   "external entity expansion (remote)", "**True**", "False (3)", "False (4)", "**True**", "untested", "False (1)", "False (5)"
+   "external entity expansion (local file)", "**True**", "False (3)", "False (4)", "**True**", "untested", "**True**", "False (5)"
+   "DTD retrieval", "**True**", "False", "False", "**True**", "untested", "False (1)", "False"
+   "gzip bomb", "False", "False", "False", "False", "**True**", "**partly** (2)", "False"
+   "xpath support", "False", "False", "False", "False", "False", "**True**", "False"
+   "xsl(t) support", "False", "False", "False", "False", "False", "**True**", "False"
+   "xinclude support", "False", "**True** (6)", "False", "False", "False", "**True** (6)", "**True**"
+   "C library", "expat", "expat", "expat", "expat", "expat", "libxml2", "expat"
 
 1. Lxml is protected against billion laughs attacks and doesn't do network
    lookups by default.
 
 parse(), parseString()
 
+defused.xmlrpclib
+-----------------
+
+TODO
+
 defused.lxml
 ------------
 
 * SAX: take feature_external_ges and feature_external_pes (?) into account
 * implement monkey patching of stdlib modules
 * document which module / library is vulnerable to which kind of attack
+* Add fix for xmlrpc's ExpatParser
 * documentation, documentation, documentation ...
 
 
                         ExternalReferenceForbidden, NotSupportedError)
 from defusedxml.common import PY3, PY26, PY31
 
+if PY3:
+    from xmlrpclib.client import ExpatParser as XmlRpcParser
+else:
+    from xmlrpclib import ExpatParser as XmlRpcParser
 
 try:
     from defusedxml import lxml
             return True
 
 
-class BaseTests(unittest.TestCase):
-    module = None
+class DefusedTestCase(unittest.TestCase):
 
     if PY3:
         content_binary = False
     else:
         content_binary = True
 
-    dtd_external_ref = False
-
-    external_ref_exception = ExternalReferenceForbidden
-    cyclic_error = None
-
     xml_dtd = os.path.join(HERE, "xmltestdata", "dtd.xml")
     xml_external = os.path.join(HERE, "xmltestdata", "external.xml")
     xml_external_file = os.path.join(HERE, "xmltestdata", "external_file.xml")
             data = f.read()
         return data
 
+
+class BaseTests(DefusedTestCase):
+    module = None
+    dtd_external_ref = False
+
+    external_ref_exception = ExternalReferenceForbidden
+    cyclic_error = None
+
+
     def test_simple_parse(self):
         self.parse(self.xml_simple)
         self.parseString(self.get_content(self.xml_simple))
     module = ElementTree
 
 
-    # etree doesn't do external ref lookup
-    external_ref_exception = ElementTree.ParseError
+    ## etree doesn't do external ref lookup
+    #external_ref_exception = ElementTree.ParseError
 
     cyclic_error = ElementTree.ParseError
 
         self.assertEqual(elements, list(root)[:1])
 
 
+class XmlRpcTarget(object):
+    def __init__(self):
+        self._data = []
+
+    def __str__(self):
+        return "\n".join(self._data)
+
+    def xml(self, encoding, standalone):
+        pass
+
+    def start(self, tag, attrs):
+        self._data.append("<%s>" % tag)
+
+    def data(self, text):
+        self._data.append(text)
+
+    def end(self, tag):
+        self._data.append("</%s>" % tag)
+
+
+class TestXmlRpc(DefusedTestCase):
+    def parse(self, xmlfile):
+        target = XmlRpcTarget()
+        parser = XmlRpcParser(target)
+        data = self.get_content(xmlfile)
+        parser.feed(data)
+        parser.close()
+        return target
+
+    def test_xmlrpc(self):
+        self.parse(self.xml_bomb)
+        self.parse(self.xml_quadratic)
+
+
 def test_main():
     suite = unittest.TestSuite()
     suite.addTests(unittest.makeSuite(TestDefusedcElementTree))
     suite.addTests(unittest.makeSuite(TestDefusedMinidom))
     suite.addTests(unittest.makeSuite(TestDefusedPulldom))
     suite.addTests(unittest.makeSuite(TestDefusedSax))
+    suite.addTests(unittest.makeSuite(TestXmlRpc))
     if lxml is not None:
         suite.addTests(unittest.makeSuite(TestDefusedLxml))
     return suite
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.