Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 124c03c

Browse files
committed
Python: Expand lxml tests
And add annotations, see PoC.py for reference Some of these needs fixing though
1 parent 3c321dd commit 124c03c

2 files changed

Lines changed: 41 additions & 28 deletions

File tree

python/ql/test/experimental/query-tests/Security/CWE-611/XmlEntityInjection.expected

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@ edges
2323
| lxml_etree.py:62:19:62:25 | ControlFlowNode for request | lxml_etree.py:62:19:62:30 | ControlFlowNode for Attribute |
2424
| lxml_etree.py:62:19:62:30 | ControlFlowNode for Attribute | lxml_etree.py:62:19:62:45 | ControlFlowNode for Subscript |
2525
| lxml_etree.py:62:19:62:45 | ControlFlowNode for Subscript | lxml_etree.py:65:34:65:44 | ControlFlowNode for xml_content |
26-
| lxml_etree.py:73:19:73:25 | ControlFlowNode for request | lxml_etree.py:73:19:73:30 | ControlFlowNode for Attribute |
27-
| lxml_etree.py:73:19:73:30 | ControlFlowNode for Attribute | lxml_etree.py:73:19:73:45 | ControlFlowNode for Subscript |
28-
| lxml_etree.py:73:19:73:45 | ControlFlowNode for Subscript | lxml_etree.py:76:34:76:44 | ControlFlowNode for xml_content |
29-
| lxml_etree.py:81:19:81:25 | ControlFlowNode for request | lxml_etree.py:81:19:81:30 | ControlFlowNode for Attribute |
30-
| lxml_etree.py:81:19:81:30 | ControlFlowNode for Attribute | lxml_etree.py:81:19:81:45 | ControlFlowNode for Subscript |
31-
| lxml_etree.py:81:19:81:45 | ControlFlowNode for Subscript | lxml_etree.py:84:34:84:44 | ControlFlowNode for xml_content |
26+
| lxml_etree.py:71:19:71:25 | ControlFlowNode for request | lxml_etree.py:71:19:71:30 | ControlFlowNode for Attribute |
27+
| lxml_etree.py:71:19:71:30 | ControlFlowNode for Attribute | lxml_etree.py:71:19:71:45 | ControlFlowNode for Subscript |
28+
| lxml_etree.py:71:19:71:45 | ControlFlowNode for Subscript | lxml_etree.py:74:34:74:44 | ControlFlowNode for xml_content |
29+
| lxml_etree.py:78:19:78:25 | ControlFlowNode for request | lxml_etree.py:78:19:78:30 | ControlFlowNode for Attribute |
30+
| lxml_etree.py:78:19:78:30 | ControlFlowNode for Attribute | lxml_etree.py:78:19:78:45 | ControlFlowNode for Subscript |
31+
| lxml_etree.py:78:19:78:45 | ControlFlowNode for Subscript | lxml_etree.py:81:34:81:44 | ControlFlowNode for xml_content |
32+
| lxml_etree.py:87:19:87:25 | ControlFlowNode for request | lxml_etree.py:87:19:87:30 | ControlFlowNode for Attribute |
33+
| lxml_etree.py:87:19:87:30 | ControlFlowNode for Attribute | lxml_etree.py:87:19:87:45 | ControlFlowNode for Subscript |
34+
| lxml_etree.py:87:19:87:45 | ControlFlowNode for Subscript | lxml_etree.py:90:34:90:44 | ControlFlowNode for xml_content |
3235
| xml_dom.py:13:19:13:25 | ControlFlowNode for request | xml_dom.py:13:19:13:30 | ControlFlowNode for Attribute |
3336
| xml_dom.py:13:19:13:30 | ControlFlowNode for Attribute | xml_dom.py:13:19:13:45 | ControlFlowNode for Subscript |
3437
| xml_dom.py:13:19:13:45 | ControlFlowNode for Subscript | xml_dom.py:15:34:15:54 | ControlFlowNode for StringIO() |
@@ -126,14 +129,18 @@ nodes
126129
| lxml_etree.py:62:19:62:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
127130
| lxml_etree.py:62:19:62:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
128131
| lxml_etree.py:65:34:65:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content |
129-
| lxml_etree.py:73:19:73:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
130-
| lxml_etree.py:73:19:73:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
131-
| lxml_etree.py:73:19:73:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
132-
| lxml_etree.py:76:34:76:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content |
133-
| lxml_etree.py:81:19:81:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
134-
| lxml_etree.py:81:19:81:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
135-
| lxml_etree.py:81:19:81:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
136-
| lxml_etree.py:84:34:84:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content |
132+
| lxml_etree.py:71:19:71:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
133+
| lxml_etree.py:71:19:71:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
134+
| lxml_etree.py:71:19:71:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
135+
| lxml_etree.py:74:34:74:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content |
136+
| lxml_etree.py:78:19:78:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
137+
| lxml_etree.py:78:19:78:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
138+
| lxml_etree.py:78:19:78:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
139+
| lxml_etree.py:81:34:81:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content |
140+
| lxml_etree.py:87:19:87:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
141+
| lxml_etree.py:87:19:87:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
142+
| lxml_etree.py:87:19:87:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
143+
| lxml_etree.py:90:34:90:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content |
137144
| xml_dom.py:13:19:13:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
138145
| xml_dom.py:13:19:13:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
139146
| xml_dom.py:13:19:13:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
@@ -228,7 +235,7 @@ subpaths
228235
| lxml_etree.py:40:34:40:44 | ControlFlowNode for xml_content | lxml_etree.py:37:19:37:25 | ControlFlowNode for request | lxml_etree.py:40:34:40:44 | ControlFlowNode for xml_content | $@ XML input is constructed from a $@ and is vulnerable to: XXE. | lxml_etree.py:40:34:40:44 | ControlFlowNode for xml_content | This | lxml_etree.py:37:19:37:25 | ControlFlowNode for request | user-provided value |
229236
| lxml_etree.py:47:34:47:44 | ControlFlowNode for xml_content | lxml_etree.py:44:19:44:25 | ControlFlowNode for request | lxml_etree.py:47:34:47:44 | ControlFlowNode for xml_content | $@ XML input is constructed from a $@ and is vulnerable to: XXE. | lxml_etree.py:47:34:47:44 | ControlFlowNode for xml_content | This | lxml_etree.py:44:19:44:25 | ControlFlowNode for request | user-provided value |
230237
| lxml_etree.py:65:34:65:44 | ControlFlowNode for xml_content | lxml_etree.py:62:19:62:25 | ControlFlowNode for request | lxml_etree.py:65:34:65:44 | ControlFlowNode for xml_content | $@ XML input is constructed from a $@ and is vulnerable to: XXE. | lxml_etree.py:65:34:65:44 | ControlFlowNode for xml_content | This | lxml_etree.py:62:19:62:25 | ControlFlowNode for request | user-provided value |
231-
| lxml_etree.py:84:34:84:44 | ControlFlowNode for xml_content | lxml_etree.py:81:19:81:25 | ControlFlowNode for request | lxml_etree.py:84:34:84:44 | ControlFlowNode for xml_content | $@ XML input is constructed from a $@ and is vulnerable to: Billion Laughs, Quadratic Blowup, XXE. | lxml_etree.py:84:34:84:44 | ControlFlowNode for xml_content | This | lxml_etree.py:81:19:81:25 | ControlFlowNode for request | user-provided value |
238+
| lxml_etree.py:81:34:81:44 | ControlFlowNode for xml_content | lxml_etree.py:78:19:78:25 | ControlFlowNode for request | lxml_etree.py:81:34:81:44 | ControlFlowNode for xml_content | $@ XML input is constructed from a $@ and is vulnerable to: Billion Laughs, Quadratic Blowup, XXE. | lxml_etree.py:81:34:81:44 | ControlFlowNode for xml_content | This | lxml_etree.py:78:19:78:25 | ControlFlowNode for request | user-provided value |
232239
| xml_dom.py:15:34:15:54 | ControlFlowNode for StringIO() | xml_dom.py:13:19:13:25 | ControlFlowNode for request | xml_dom.py:15:34:15:54 | ControlFlowNode for StringIO() | $@ XML input is constructed from a $@ and is vulnerable to: Billion Laughs, Quadratic Blowup. | xml_dom.py:15:34:15:54 | ControlFlowNode for StringIO() | This | xml_dom.py:13:19:13:25 | ControlFlowNode for request | user-provided value |
233240
| xml_dom.py:21:40:21:50 | ControlFlowNode for xml_content | xml_dom.py:19:19:19:25 | ControlFlowNode for request | xml_dom.py:21:40:21:50 | ControlFlowNode for xml_content | $@ XML input is constructed from a $@ and is vulnerable to: Billion Laughs, Quadratic Blowup. | xml_dom.py:21:40:21:50 | ControlFlowNode for xml_content | This | xml_dom.py:19:19:19:25 | ControlFlowNode for request | user-provided value |
234241
| xml_dom.py:27:34:27:54 | ControlFlowNode for StringIO() | xml_dom.py:25:19:25:25 | ControlFlowNode for request | xml_dom.py:27:34:27:54 | ControlFlowNode for StringIO() | $@ XML input is constructed from a $@ and is vulnerable to: Billion Laughs, Quadratic Blowup. | xml_dom.py:27:34:27:54 | ControlFlowNode for StringIO() | This | xml_dom.py:25:19:25:25 | ControlFlowNode for request | user-provided value |

python/ql/test/experimental/query-tests/Security/CWE-611/lxml_etree.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,25 @@
1010
def lxml_etree_fromstring():
1111
xml_content = request.args['xml_content']
1212

13-
return lxml.etree.fromstring(xml_content).text
13+
return lxml.etree.fromstring(xml_content).text # NOT OK for XXE
1414

1515
@app.route("/lxml_etree_fromstringlist")
1616
def lxml_etree_fromstringlist():
1717
xml_content = request.args['xml_content']
1818

19-
return lxml.etree.fromstringlist([xml_content]).text
19+
return lxml.etree.fromstringlist([xml_content]).text # NOT OK for XXE
2020

2121
@app.route("/lxml_etree_XML")
2222
def lxml_etree_XML():
2323
xml_content = request.args['xml_content']
2424

25-
return lxml.etree.XML(xml_content).text
25+
return lxml.etree.XML(xml_content).text # NOT OK for XXE
2626

2727
@app.route("/lxml_etree_parse")
2828
def lxml_etree_parse():
2929
xml_content = request.args['xml_content']
3030

31-
return lxml.etree.parse(StringIO(xml_content)).getroot().text
31+
return lxml.etree.parse(StringIO(xml_content)).getroot().text # NOT OK for XXE
3232

3333
# With parsers - Default
3434

@@ -37,14 +37,14 @@ def lxml_parser():
3737
xml_content = request.args['xml_content']
3838

3939
parser = lxml.etree.XMLParser()
40-
return lxml.etree.fromstring(xml_content, parser=parser).text
40+
return lxml.etree.fromstring(xml_content, parser=parser).text # NOT OK for XXE
4141

4242
@app.route("/lxml_etree_fromstring-lxml.etree.get_default_parser")
4343
def lxml_parser():
4444
xml_content = request.args['xml_content']
4545

4646
parser = lxml.etree.get_default_parser()
47-
return lxml.etree.fromstring(xml_content, parser=parser).text
47+
return lxml.etree.fromstring(xml_content, parser=parser).text # NOT OK for XXE
4848

4949
# With parsers - With options
5050

@@ -54,31 +54,37 @@ def lxml_parser():
5454
xml_content = request.args['xml_content']
5555

5656
parser = lxml.etree.XMLParser(resolve_entities=False)
57-
return lxml.etree.fromstring(xml_content, parser=parser).text
57+
return lxml.etree.fromstring(xml_content, parser=parser).text # OK for XXE
5858

5959
# XXE-vuln
6060
@app.route("/lxml_etree_fromstring-lxml.etree.XMLParser+")
6161
def lxml_parser():
6262
xml_content = request.args['xml_content']
6363

6464
parser = lxml.etree.XMLParser(resolve_entities=True)
65-
return lxml.etree.fromstring(xml_content, parser=parser).text
65+
return lxml.etree.fromstring(xml_content, parser=parser).text # NOT OK for XXE
6666

6767
# Billion laughs and quadratic blowup (huge_tree)
6868

69-
## Good (huge_tree=True but resolve_entities=False)
70-
7169
@app.route("/lxml_etree_fromstring-lxml.etree.XMLParser+")
7270
def lxml_parser():
7371
xml_content = request.args['xml_content']
7472

7573
parser = lxml.etree.XMLParser(resolve_entities=False, huge_tree=True)
76-
return lxml.etree.fromstring(xml_content, parser=parser).text
74+
return lxml.etree.fromstring(xml_content, parser=parser).text # OK for XXE, NOT OK for billion laughs/quadratic
7775

78-
## Bad
7976
@app.route("/lxml_etree_fromstring-lxml.etree.XMLParser+")
8077
def lxml_parser():
8178
xml_content = request.args['xml_content']
8279

8380
parser = lxml.etree.XMLParser(huge_tree=True)
84-
return lxml.etree.fromstring(xml_content, parser=parser).text
81+
return lxml.etree.fromstring(xml_content, parser=parser).text # NOT OK for XXE, NOT OK for billion laughs/quadratic
82+
83+
# DTD retrival
84+
85+
@app.route("/lxml_etree_fromstring-lxml.etree.XMLParser+")
86+
def lxml_parser():
87+
xml_content = request.args['xml_content']
88+
89+
parser = lxml.etree.XMLParser(resolve_entities=False, load_dtd=True, no_network=False)
90+
return lxml.etree.fromstring(xml_content, parser=parser).text # NOT OK for DTD, OK for rest

0 commit comments

Comments
 (0)