Skip to content

Commit 7728b6c

Browse files
committed
Python: Change XmlBomb vulnerability kind
1 parent f2f0873 commit 7728b6c

File tree

12 files changed

+73
-78
lines changed

12 files changed

+73
-78
lines changed

python/ql/lib/semmle/python/Concepts.qll

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -507,15 +507,18 @@ module XML {
507507
* See PoC at `python/PoCs/XmlParsing/PoC.py` for some tests of vulnerable XML parsing.
508508
*/
509509
class XmlParsingVulnerabilityKind extends string {
510-
XmlParsingVulnerabilityKind() {
511-
this in ["Billion Laughs", "Quadratic Blowup", "XXE", "DTD retrieval"]
512-
}
513-
514-
/** Holds for Billion Laughs vulnerability kind. */
515-
predicate isBillionLaughs() { this = "Billion Laughs" }
510+
XmlParsingVulnerabilityKind() { this in ["XML bomb", "XXE", "DTD retrieval"] }
516511

517-
/** Holds for Quadratic Blowup vulnerability kind. */
518-
predicate isQuadraticBlowup() { this = "Quadratic Blowup" }
512+
/**
513+
* Holds for XML bomb vulnerability kind, such as 'Billion Laughs' and 'Quadratic
514+
* Blowup'.
515+
*
516+
* While a parser could technically be vulnerable to one and not the other, from our
517+
* point of view the interesting part is that it IS vulnerable to these types of
518+
* attacks, and not so much which one specifically works. In practice I haven't seen
519+
* a parser that is vulnerable to one and not the other.
520+
*/
521+
predicate isXmlBomb() { this = "XML bomb" }
519522

520523
/** Holds for XXE vulnerability kind. */
521524
predicate isXxe() { this = "XXE" }

python/ql/lib/semmle/python/frameworks/Lxml.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private module Lxml {
144144
this.getKeywordParameter("resolve_entities").getAValueReachingRhs().asExpr() = any(True t)
145145
)
146146
or
147-
(kind.isBillionLaughs() or kind.isQuadraticBlowup()) and
147+
kind.isXmlBomb() and
148148
this.getKeywordParameter("huge_tree").getAValueReachingRhs().asExpr() = any(True t) and
149149
not this.getKeywordParameter("resolve_entities").getAValueReachingRhs().asExpr() =
150150
any(False t)
@@ -318,7 +318,7 @@ private module Lxml {
318318
// note that there is no `resolve_entities` argument, so it's not possible to turn off XXE :O
319319
kind.isXxe()
320320
or
321-
(kind.isBillionLaughs() or kind.isQuadraticBlowup()) and
321+
kind.isXmlBomb() and
322322
this.getKeywordParameter("huge_tree").getAValueReachingRhs().asExpr() = any(True t)
323323
or
324324
kind.isDtdRetrieval() and

python/ql/lib/semmle/python/frameworks/Stdlib.qll

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3241,9 +3241,7 @@ private module StdlibPrivate {
32413241

32423242
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
32433243

3244-
override predicate vulnerableTo(XML::XmlParsingVulnerabilityKind kind) {
3245-
kind.isBillionLaughs() or kind.isQuadraticBlowup()
3246-
}
3244+
override predicate vulnerableTo(XML::XmlParsingVulnerabilityKind kind) { kind.isXmlBomb() }
32473245

32483246
override predicate mayExecuteInput() { none() }
32493247

@@ -3301,7 +3299,7 @@ private module StdlibPrivate {
33013299
override predicate vulnerableTo(XML::XmlParsingVulnerabilityKind kind) {
33023300
// note: it does not matter what `xml.etree` parser you are using, you cannot
33033301
// change the security features anyway :|
3304-
kind.isBillionLaughs() or kind.isQuadraticBlowup()
3302+
kind.isXmlBomb()
33053303
}
33063304

33073305
override predicate mayExecuteInput() { none() }
@@ -3461,7 +3459,7 @@ private module StdlibPrivate {
34613459

34623460
override predicate vulnerableTo(XML::XmlParsingVulnerabilityKind kind) {
34633461
// always vuln to these
3464-
(kind.isBillionLaughs() or kind.isQuadraticBlowup())
3462+
kind.isXmlBomb()
34653463
or
34663464
// can be vuln to other things if features has been turned on
34673465
this.getObject() = saxParserWithFeatureExternalGesTurnedOn() and
@@ -3514,7 +3512,7 @@ private module StdlibPrivate {
35143512

35153513
override predicate vulnerableTo(XML::XmlParsingVulnerabilityKind kind) {
35163514
// always vuln to these
3517-
(kind.isBillionLaughs() or kind.isQuadraticBlowup())
3515+
kind.isXmlBomb()
35183516
}
35193517

35203518
override predicate mayExecuteInput() { none() }
@@ -3590,7 +3588,7 @@ private module StdlibPrivate {
35903588
this.getParserArg() = saxParserWithFeatureExternalGesTurnedOn() and
35913589
(kind.isXxe() or kind.isDtdRetrieval())
35923590
or
3593-
(kind.isBillionLaughs() or kind.isQuadraticBlowup())
3591+
kind.isXmlBomb()
35943592
}
35953593

35963594
override predicate mayExecuteInput() { none() }

python/ql/lib/semmle/python/frameworks/Xmltodict.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ private module Xmltodict {
2828
}
2929

3030
override predicate vulnerableTo(XML::XmlParsingVulnerabilityKind kind) {
31-
(kind.isBillionLaughs() or kind.isQuadraticBlowup()) and
31+
kind.isXmlBomb() and
3232
this.getKeywordParameter("disable_entities").getAValueReachingRhs().asExpr() = any(False f)
3333
}
3434

python/ql/src/experimental/Security/CWE-611/SimpleXmlRpcServer.ql

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,7 @@ private import python
1313
private import semmle.python.Concepts
1414
private import semmle.python.ApiGraphs
1515

16-
from DataFlow::CallCfgNode call, string kinds
16+
from DataFlow::CallCfgNode call
1717
where
18-
call = API::moduleImport("xmlrpc").getMember("server").getMember("SimpleXMLRPCServer").getACall() and
19-
kinds =
20-
strictconcat(XML::XmlParsingVulnerabilityKind kind |
21-
kind.isBillionLaughs() or kind.isQuadraticBlowup()
22-
|
23-
kind, ", "
24-
)
25-
select call, "SimpleXMLRPCServer is vulnerable to: " + kinds + "."
18+
call = API::moduleImport("xmlrpc").getMember("server").getMember("SimpleXMLRPCServer").getACall()
19+
select call, "SimpleXMLRPCServer is vulnerable to XML bombs"

python/ql/src/experimental/semmle/python/security/dataflow/XmlBombCustomizations.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ module XmlBomb {
4141
class XmlParsingWithEntityResolution extends Sink {
4242
XmlParsingWithEntityResolution() {
4343
exists(XML::XmlParsing parsing, XML::XmlParsingVulnerabilityKind kind |
44-
(kind.isBillionLaughs() or kind.isQuadraticBlowup()) and
44+
kind.isXmlBomb() and
4545
parsing.vulnerableTo(kind) and
4646
this = parsing.getAnInput()
4747
)

python/ql/test/library-tests/frameworks/lxml/parsing.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050

5151
# Billion laughs vuln (also XXE)
5252
parser = lxml.etree.XMLParser(huge_tree=True)
53-
lxml.etree.fromstring(x, parser=parser) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' xmlVuln='XXE' decodeOutput=lxml.etree.fromstring(..)
53+
lxml.etree.fromstring(x, parser=parser) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' xmlVuln='XXE' decodeOutput=lxml.etree.fromstring(..)
5454

5555
# Safe for both Billion laughs and XXE
5656
parser = lxml.etree.XMLParser(resolve_entities=False, huge_tree=True)
@@ -63,5 +63,5 @@
6363
# iterparse configurations ... this doesn't use a parser argument but takes MOST (!) of
6464
# the normal XMLParser arguments. Specifically, it doesn't allow disabling XXE :O
6565

66-
lxml.etree.iterparse(xml_file, huge_tree=True) # $ decodeFormat=XML decodeInput=xml_file xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' xmlVuln='XXE' decodeOutput=lxml.etree.iterparse(..) getAPathArgument=xml_file
66+
lxml.etree.iterparse(xml_file, huge_tree=True) # $ decodeFormat=XML decodeInput=xml_file xmlVuln='XML bomb' xmlVuln='XXE' decodeOutput=lxml.etree.iterparse(..) getAPathArgument=xml_file
6767
lxml.etree.iterparse(xml_file, load_dtd=True, no_network=False) # $ decodeFormat=XML decodeInput=xml_file xmlVuln='DTD retrieval' xmlVuln='XXE' decodeOutput=lxml.etree.iterparse(..) getAPathArgument=xml_file

python/ql/test/library-tests/frameworks/stdlib/XPathExecution.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22
ns = {'dc': 'http://purl.org/dc/elements/1.1/'}
33

44
import xml.etree.ElementTree as ET
5-
tree = ET.parse('country_data.xml') # $ decodeFormat=XML decodeInput='country_data.xml' decodeOutput=ET.parse(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' getAPathArgument='country_data.xml'
5+
tree = ET.parse('country_data.xml') # $ decodeFormat=XML decodeInput='country_data.xml' decodeOutput=ET.parse(..) xmlVuln='XML bomb' getAPathArgument='country_data.xml'
66
root = tree.getroot()
77

88
root.find(match, namespaces=ns) # $ getXPath=match
99
root.findall(match, namespaces=ns) # $ getXPath=match
1010
root.findtext(match, default=None, namespaces=ns) # $ getXPath=match
1111

1212
tree = ET.ElementTree()
13-
tree.parse("index.xhtml") # $ decodeFormat=XML decodeInput="index.xhtml" decodeOutput=tree.parse(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' getAPathArgument="index.xhtml"
13+
tree.parse("index.xhtml") # $ decodeFormat=XML decodeInput="index.xhtml" decodeOutput=tree.parse(..) xmlVuln='XML bomb' getAPathArgument="index.xhtml"
1414

1515
tree.find(match, namespaces=ns) # $ getXPath=match
1616
tree.findall(match, namespaces=ns) # $ getXPath=match
1717
tree.findtext(match, default=None, namespaces=ns) # $ getXPath=match
1818

1919
parser = ET.XMLParser()
20-
parser.feed("<foo>bar</foo>") # $ decodeFormat=XML decodeInput="<foo>bar</foo>" xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
20+
parser.feed("<foo>bar</foo>") # $ decodeFormat=XML decodeInput="<foo>bar</foo>" xmlVuln='XML bomb'
2121
tree = parser.close() # $ decodeOutput=parser.close()
2222
tree.find(match, namespaces=ns) # $ getXPath=match

python/ql/test/library-tests/frameworks/stdlib/xml_dom.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,26 @@
66
x = "some xml"
77

88
# minidom
9-
xml.dom.minidom.parse(StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.dom.minidom.parse(..) getAPathArgument=StringIO(..)
10-
xml.dom.minidom.parse(file=StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.dom.minidom.parse(..) getAPathArgument=StringIO(..)
9+
xml.dom.minidom.parse(StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' decodeOutput=xml.dom.minidom.parse(..) getAPathArgument=StringIO(..)
10+
xml.dom.minidom.parse(file=StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' decodeOutput=xml.dom.minidom.parse(..) getAPathArgument=StringIO(..)
1111

12-
xml.dom.minidom.parseString(x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.dom.minidom.parseString(..)
13-
xml.dom.minidom.parseString(string=x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.dom.minidom.parseString(..)
12+
xml.dom.minidom.parseString(x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.dom.minidom.parseString(..)
13+
xml.dom.minidom.parseString(string=x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.dom.minidom.parseString(..)
1414

1515

1616
# pulldom
17-
xml.dom.pulldom.parse(StringIO(x))['START_DOCUMENT'][1] # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.dom.pulldom.parse(..) getAPathArgument=StringIO(..)
18-
xml.dom.pulldom.parse(stream_or_string=StringIO(x))['START_DOCUMENT'][1] # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.dom.pulldom.parse(..) getAPathArgument=StringIO(..)
17+
xml.dom.pulldom.parse(StringIO(x))['START_DOCUMENT'][1] # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' decodeOutput=xml.dom.pulldom.parse(..) getAPathArgument=StringIO(..)
18+
xml.dom.pulldom.parse(stream_or_string=StringIO(x))['START_DOCUMENT'][1] # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' decodeOutput=xml.dom.pulldom.parse(..) getAPathArgument=StringIO(..)
1919

20-
xml.dom.pulldom.parseString(x)['START_DOCUMENT'][1] # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.dom.pulldom.parseString(..)
21-
xml.dom.pulldom.parseString(string=x)['START_DOCUMENT'][1] # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.dom.pulldom.parseString(..)
20+
xml.dom.pulldom.parseString(x)['START_DOCUMENT'][1] # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.dom.pulldom.parseString(..)
21+
xml.dom.pulldom.parseString(string=x)['START_DOCUMENT'][1] # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.dom.pulldom.parseString(..)
2222

2323

2424
# These are based on SAX parses, and you can specify your own, so you can expose yourself to XXE (yay/)
2525
parser = xml.sax.make_parser()
2626
parser.setFeature(xml.sax.handler.feature_external_ges, True)
27-
xml.dom.minidom.parse(StringIO(x), parser) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE' decodeOutput=xml.dom.minidom.parse(..) getAPathArgument=StringIO(..)
28-
xml.dom.minidom.parse(StringIO(x), parser=parser) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE' decodeOutput=xml.dom.minidom.parse(..) getAPathArgument=StringIO(..)
27+
xml.dom.minidom.parse(StringIO(x), parser) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' xmlVuln='DTD retrieval' xmlVuln='XXE' decodeOutput=xml.dom.minidom.parse(..) getAPathArgument=StringIO(..)
28+
xml.dom.minidom.parse(StringIO(x), parser=parser) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' xmlVuln='DTD retrieval' xmlVuln='XXE' decodeOutput=xml.dom.minidom.parse(..) getAPathArgument=StringIO(..)
2929

30-
xml.dom.pulldom.parse(StringIO(x), parser) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE' decodeOutput=xml.dom.pulldom.parse(..) getAPathArgument=StringIO(..)
31-
xml.dom.pulldom.parse(StringIO(x), parser=parser) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE' decodeOutput=xml.dom.pulldom.parse(..) getAPathArgument=StringIO(..)
30+
xml.dom.pulldom.parse(StringIO(x), parser) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' xmlVuln='DTD retrieval' xmlVuln='XXE' decodeOutput=xml.dom.pulldom.parse(..) getAPathArgument=StringIO(..)
31+
xml.dom.pulldom.parse(StringIO(x), parser=parser) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' xmlVuln='DTD retrieval' xmlVuln='XXE' decodeOutput=xml.dom.pulldom.parse(..) getAPathArgument=StringIO(..)

python/ql/test/library-tests/frameworks/stdlib/xml_etree.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,43 @@
44
x = "some xml"
55

66
# Parsing in different ways
7-
xml.etree.ElementTree.fromstring(x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.fromstring(..)
8-
xml.etree.ElementTree.fromstring(text=x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.fromstring(..)
7+
xml.etree.ElementTree.fromstring(x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.fromstring(..)
8+
xml.etree.ElementTree.fromstring(text=x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.fromstring(..)
99

10-
xml.etree.ElementTree.fromstringlist([x]) # $ decodeFormat=XML decodeInput=List xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.fromstringlist(..)
11-
xml.etree.ElementTree.fromstringlist(sequence=[x]) # $ decodeFormat=XML decodeInput=List xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.fromstringlist(..)
10+
xml.etree.ElementTree.fromstringlist([x]) # $ decodeFormat=XML decodeInput=List xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.fromstringlist(..)
11+
xml.etree.ElementTree.fromstringlist(sequence=[x]) # $ decodeFormat=XML decodeInput=List xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.fromstringlist(..)
1212

13-
xml.etree.ElementTree.XML(x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.XML(..)
14-
xml.etree.ElementTree.XML(text=x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.XML(..)
13+
xml.etree.ElementTree.XML(x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.XML(..)
14+
xml.etree.ElementTree.XML(text=x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.XML(..)
1515

16-
xml.etree.ElementTree.XMLID(x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.XMLID(..)
17-
xml.etree.ElementTree.XMLID(text=x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.XMLID(..)
16+
xml.etree.ElementTree.XMLID(x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.XMLID(..)
17+
xml.etree.ElementTree.XMLID(text=x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.XMLID(..)
1818

19-
xml.etree.ElementTree.parse(StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.parse(..) getAPathArgument=StringIO(..)
20-
xml.etree.ElementTree.parse(source=StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.parse(..) getAPathArgument=StringIO(..)
19+
xml.etree.ElementTree.parse(StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.parse(..) getAPathArgument=StringIO(..)
20+
xml.etree.ElementTree.parse(source=StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.parse(..) getAPathArgument=StringIO(..)
2121

22-
xml.etree.ElementTree.iterparse(StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.iterparse(..) getAPathArgument=StringIO(..)
23-
xml.etree.ElementTree.iterparse(source=StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.iterparse(..) getAPathArgument=StringIO(..)
22+
xml.etree.ElementTree.iterparse(StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.iterparse(..) getAPathArgument=StringIO(..)
23+
xml.etree.ElementTree.iterparse(source=StringIO(x)) # $ decodeFormat=XML decodeInput=StringIO(..) xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.iterparse(..) getAPathArgument=StringIO(..)
2424

2525
tree = xml.etree.ElementTree.ElementTree()
26-
tree.parse("file.xml") # $ decodeFormat=XML decodeInput="file.xml" xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=tree.parse(..) getAPathArgument="file.xml"
27-
tree.parse(source="file.xml") # $ decodeFormat=XML decodeInput="file.xml" xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=tree.parse(..) getAPathArgument="file.xml"
26+
tree.parse("file.xml") # $ decodeFormat=XML decodeInput="file.xml" xmlVuln='XML bomb' decodeOutput=tree.parse(..) getAPathArgument="file.xml"
27+
tree.parse(source="file.xml") # $ decodeFormat=XML decodeInput="file.xml" xmlVuln='XML bomb' decodeOutput=tree.parse(..) getAPathArgument="file.xml"
2828

2929

3030
# With parsers (no options available to disable/enable security features)
3131
parser = xml.etree.ElementTree.XMLParser()
32-
xml.etree.ElementTree.fromstring(x, parser=parser) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' decodeOutput=xml.etree.ElementTree.fromstring(..)
32+
xml.etree.ElementTree.fromstring(x, parser=parser) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb' decodeOutput=xml.etree.ElementTree.fromstring(..)
3333

3434
# manual use of feed method
3535
parser = xml.etree.ElementTree.XMLParser()
36-
parser.feed(x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
37-
parser.feed(data=x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
36+
parser.feed(x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb'
37+
parser.feed(data=x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb'
3838
parser.close() # $ decodeOutput=parser.close()
3939

4040
# manual use of feed method on XMLPullParser
4141
parser = xml.etree.ElementTree.XMLPullParser()
42-
parser.feed(x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
43-
parser.feed(data=x) # $ decodeFormat=XML decodeInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
42+
parser.feed(x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb'
43+
parser.feed(data=x) # $ decodeFormat=XML decodeInput=x xmlVuln='XML bomb'
4444
parser.close() # $ decodeOutput=parser.close()
4545

4646
# note: it's technically possible to use the thing wrapper func `fromstring` with an

0 commit comments

Comments
 (0)