mirror of
https://github.com/github/codeql.git
synced 2025-12-23 12:16:33 +01:00
Python: Promote XMLParsing concept test
This commit is contained in:
committed by
Rasmus Wriedt Larsen
parent
e45288e812
commit
35ccba2ec1
@@ -0,0 +1,3 @@
|
|||||||
|
import python
|
||||||
|
import experimental.meta.ConceptsTest
|
||||||
|
import experimental.semmle.python.frameworks.Xml // needed until modeling have been promoted
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
import python
|
|
||||||
import semmle.python.Concepts
|
|
||||||
import experimental.semmle.python.frameworks.Xml
|
|
||||||
import semmle.python.dataflow.new.DataFlow
|
|
||||||
import TestUtilities.InlineExpectationsTest
|
|
||||||
private import semmle.python.dataflow.new.internal.PrintNode
|
|
||||||
|
|
||||||
class XmlParsingTest extends InlineExpectationsTest {
|
|
||||||
XmlParsingTest() { this = "XmlParsingTest" }
|
|
||||||
|
|
||||||
override string getARelevantTag() { result in ["input", "vuln"] }
|
|
||||||
|
|
||||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
|
||||||
exists(location.getFile().getRelativePath()) and
|
|
||||||
exists(XML::XMLParsing parsing |
|
|
||||||
exists(DataFlow::Node input |
|
|
||||||
input = parsing.getAnInput() and
|
|
||||||
location = input.getLocation() and
|
|
||||||
element = input.toString() and
|
|
||||||
value = prettyNodeForInlineTest(input) and
|
|
||||||
tag = "input"
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(XML::XMLParsingVulnerabilityKind kind |
|
|
||||||
parsing.vulnerableTo(kind) and
|
|
||||||
location = parsing.getLocation() and
|
|
||||||
element = parsing.toString() and
|
|
||||||
value = "'" + kind + "'" and
|
|
||||||
tag = "vuln"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,51 +4,51 @@ import lxml.etree
|
|||||||
x = "some xml"
|
x = "some xml"
|
||||||
|
|
||||||
# different parsing methods
|
# different parsing methods
|
||||||
lxml.etree.fromstring(x) # $ input=x vuln='XXE'
|
lxml.etree.fromstring(x) # $ xmlInput=x xmlVuln='XXE'
|
||||||
lxml.etree.fromstring(text=x) # $ input=x vuln='XXE'
|
lxml.etree.fromstring(text=x) # $ xmlInput=x xmlVuln='XXE'
|
||||||
|
|
||||||
lxml.etree.fromstringlist([x]) # $ input=List vuln='XXE'
|
lxml.etree.fromstringlist([x]) # $ xmlInput=List xmlVuln='XXE'
|
||||||
lxml.etree.fromstringlist(strings=[x]) # $ input=List vuln='XXE'
|
lxml.etree.fromstringlist(strings=[x]) # $ xmlInput=List xmlVuln='XXE'
|
||||||
|
|
||||||
lxml.etree.XML(x) # $ input=x vuln='XXE'
|
lxml.etree.XML(x) # $ xmlInput=x xmlVuln='XXE'
|
||||||
lxml.etree.XML(text=x) # $ input=x vuln='XXE'
|
lxml.etree.XML(text=x) # $ xmlInput=x xmlVuln='XXE'
|
||||||
|
|
||||||
lxml.etree.parse(StringIO(x)) # $ input=StringIO(..) vuln='XXE'
|
lxml.etree.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='XXE'
|
||||||
lxml.etree.parse(source=StringIO(x)) # $ input=StringIO(..) vuln='XXE'
|
lxml.etree.parse(source=StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='XXE'
|
||||||
|
|
||||||
lxml.etree.parseid(StringIO(x)) # $ input=StringIO(..) vuln='XXE'
|
lxml.etree.parseid(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='XXE'
|
||||||
lxml.etree.parseid(source=StringIO(x)) # $ input=StringIO(..) vuln='XXE'
|
lxml.etree.parseid(source=StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='XXE'
|
||||||
|
|
||||||
# With default parsers (nothing changed)
|
# With default parsers (nothing changed)
|
||||||
parser = lxml.etree.XMLParser()
|
parser = lxml.etree.XMLParser()
|
||||||
lxml.etree.fromstring(x, parser=parser) # $ input=x vuln='XXE'
|
lxml.etree.fromstring(x, parser=parser) # $ xmlInput=x xmlVuln='XXE'
|
||||||
|
|
||||||
parser = lxml.etree.get_default_parser()
|
parser = lxml.etree.get_default_parser()
|
||||||
lxml.etree.fromstring(x, parser=parser) # $ input=x vuln='XXE'
|
lxml.etree.fromstring(x, parser=parser) # $ xmlInput=x xmlVuln='XXE'
|
||||||
|
|
||||||
# manual use of feed method
|
# manual use of feed method
|
||||||
parser = lxml.etree.XMLParser()
|
parser = lxml.etree.XMLParser()
|
||||||
parser.feed(x) # $ input=x vuln='XXE'
|
parser.feed(x) # $ xmlInput=x xmlVuln='XXE'
|
||||||
parser.feed(data=x) # $ input=x vuln='XXE'
|
parser.feed(data=x) # $ xmlInput=x xmlVuln='XXE'
|
||||||
parser.close()
|
parser.close()
|
||||||
|
|
||||||
# XXE-safe
|
# XXE-safe
|
||||||
parser = lxml.etree.XMLParser(resolve_entities=False)
|
parser = lxml.etree.XMLParser(resolve_entities=False)
|
||||||
lxml.etree.fromstring(x, parser) # $ input=x
|
lxml.etree.fromstring(x, parser) # $ xmlInput=x
|
||||||
lxml.etree.fromstring(x, parser=parser) # $ input=x
|
lxml.etree.fromstring(x, parser=parser) # $ xmlInput=x
|
||||||
|
|
||||||
# XXE-vuln
|
# XXE-vuln
|
||||||
parser = lxml.etree.XMLParser(resolve_entities=True)
|
parser = lxml.etree.XMLParser(resolve_entities=True)
|
||||||
lxml.etree.fromstring(x, parser=parser) # $ input=x vuln='XXE'
|
lxml.etree.fromstring(x, parser=parser) # $ xmlInput=x xmlVuln='XXE'
|
||||||
|
|
||||||
# Billion laughs vuln (also XXE)
|
# Billion laughs vuln (also XXE)
|
||||||
parser = lxml.etree.XMLParser(huge_tree=True)
|
parser = lxml.etree.XMLParser(huge_tree=True)
|
||||||
lxml.etree.fromstring(x, parser=parser) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup' vuln='XXE'
|
lxml.etree.fromstring(x, parser=parser) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup' xmlVuln='XXE'
|
||||||
|
|
||||||
# Safe for both Billion laughs and XXE
|
# Safe for both Billion laughs and XXE
|
||||||
parser = lxml.etree.XMLParser(resolve_entities=False, huge_tree=True)
|
parser = lxml.etree.XMLParser(resolve_entities=False, huge_tree=True)
|
||||||
lxml.etree.fromstring(x, parser=parser) # $ input=x
|
lxml.etree.fromstring(x, parser=parser) # $ xmlInput=x
|
||||||
|
|
||||||
# DTD retrival vuln (also XXE)
|
# DTD retrival vuln (also XXE)
|
||||||
parser = lxml.etree.XMLParser(load_dtd=True, no_network=False)
|
parser = lxml.etree.XMLParser(load_dtd=True, no_network=False)
|
||||||
lxml.etree.fromstring(x, parser=parser) # $ input=x vuln='DTD retrieval' vuln='XXE'
|
lxml.etree.fromstring(x, parser=parser) # $ xmlInput=x xmlVuln='DTD retrieval' xmlVuln='XXE'
|
||||||
|
|||||||
@@ -6,26 +6,26 @@ import xml.sax
|
|||||||
x = "some xml"
|
x = "some xml"
|
||||||
|
|
||||||
# minidom
|
# minidom
|
||||||
xml.dom.minidom.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.dom.minidom.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.dom.minidom.parse(file=StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.dom.minidom.parse(file=StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
xml.dom.minidom.parseString(x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.dom.minidom.parseString(x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.dom.minidom.parseString(string=x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.dom.minidom.parseString(string=x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
|
|
||||||
# pulldom
|
# pulldom
|
||||||
xml.dom.pulldom.parse(StringIO(x))['START_DOCUMENT'][1] # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.dom.pulldom.parse(StringIO(x))['START_DOCUMENT'][1] # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.dom.pulldom.parse(stream_or_string=StringIO(x))['START_DOCUMENT'][1] # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.dom.pulldom.parse(stream_or_string=StringIO(x))['START_DOCUMENT'][1] # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
xml.dom.pulldom.parseString(x)['START_DOCUMENT'][1] # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.dom.pulldom.parseString(x)['START_DOCUMENT'][1] # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.dom.pulldom.parseString(string=x)['START_DOCUMENT'][1] # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.dom.pulldom.parseString(string=x)['START_DOCUMENT'][1] # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
|
|
||||||
# These are based on SAX parses, and you can specify your own, so you can expose yourself to XXE (yay/)
|
# These are based on SAX parses, and you can specify your own, so you can expose yourself to XXE (yay/)
|
||||||
parser = xml.sax.make_parser()
|
parser = xml.sax.make_parser()
|
||||||
parser.setFeature(xml.sax.handler.feature_external_ges, True)
|
parser.setFeature(xml.sax.handler.feature_external_ges, True)
|
||||||
xml.dom.minidom.parse(StringIO(x), parser) # $ input=StringIO(..) vuln='Billion Laughs' vuln='DTD retrieval' vuln='Quadratic Blowup' vuln='XXE'
|
xml.dom.minidom.parse(StringIO(x), parser) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE'
|
||||||
xml.dom.minidom.parse(StringIO(x), parser=parser) # $ input=StringIO(..) vuln='Billion Laughs' vuln='DTD retrieval' vuln='Quadratic Blowup' vuln='XXE'
|
xml.dom.minidom.parse(StringIO(x), parser=parser) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE'
|
||||||
|
|
||||||
xml.dom.pulldom.parse(StringIO(x), parser) # $ input=StringIO(..) vuln='Billion Laughs' vuln='DTD retrieval' vuln='Quadratic Blowup' vuln='XXE'
|
xml.dom.pulldom.parse(StringIO(x), parser) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE'
|
||||||
xml.dom.pulldom.parse(StringIO(x), parser=parser) # $ input=StringIO(..) vuln='Billion Laughs' vuln='DTD retrieval' vuln='Quadratic Blowup' vuln='XXE'
|
xml.dom.pulldom.parse(StringIO(x), parser=parser) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE'
|
||||||
|
|||||||
@@ -4,39 +4,39 @@ import xml.etree.ElementTree
|
|||||||
x = "some xml"
|
x = "some xml"
|
||||||
|
|
||||||
# Parsing in different ways
|
# Parsing in different ways
|
||||||
xml.etree.ElementTree.fromstring(x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.fromstring(x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.etree.ElementTree.fromstring(text=x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.fromstring(text=x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
xml.etree.ElementTree.fromstringlist([x]) # $ input=List vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.fromstringlist([x]) # $ xmlInput=List xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.etree.ElementTree.fromstringlist(sequence=[x]) # $ input=List vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.fromstringlist(sequence=[x]) # $ xmlInput=List xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
xml.etree.ElementTree.XML(x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.XML(x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.etree.ElementTree.XML(text=x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.XML(text=x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
xml.etree.ElementTree.XMLID(x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.XMLID(x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.etree.ElementTree.XMLID(text=x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.XMLID(text=x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
xml.etree.ElementTree.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.etree.ElementTree.parse(source=StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.parse(source=StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
xml.etree.ElementTree.iterparse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.iterparse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.etree.ElementTree.iterparse(source=StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.iterparse(source=StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
|
|
||||||
# With parsers (no options available to disable/enable security features)
|
# With parsers (no options available to disable/enable security features)
|
||||||
parser = xml.etree.ElementTree.XMLParser()
|
parser = xml.etree.ElementTree.XMLParser()
|
||||||
xml.etree.ElementTree.fromstring(x, parser=parser) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.etree.ElementTree.fromstring(x, parser=parser) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
# manual use of feed method
|
# manual use of feed method
|
||||||
parser = xml.etree.ElementTree.XMLParser()
|
parser = xml.etree.ElementTree.XMLParser()
|
||||||
parser.feed(x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
parser.feed(x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
parser.feed(data=x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
parser.feed(data=x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
parser.close()
|
parser.close()
|
||||||
|
|
||||||
# manual use of feed method on XMLPullParser
|
# manual use of feed method on XMLPullParser
|
||||||
parser = xml.etree.ElementTree.XMLPullParser()
|
parser = xml.etree.ElementTree.XMLPullParser()
|
||||||
parser.feed(x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
parser.feed(x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
parser.feed(data=x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
parser.feed(data=x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
parser.close()
|
parser.close()
|
||||||
|
|
||||||
# note: it's technically possible to use the thing wrapper func `fromstring` with an
|
# note: it's technically possible to use the thing wrapper func `fromstring` with an
|
||||||
|
|||||||
@@ -10,41 +10,41 @@ class MainHandler(xml.sax.ContentHandler):
|
|||||||
def characters(self, data):
|
def characters(self, data):
|
||||||
self._result.append(data)
|
self._result.append(data)
|
||||||
|
|
||||||
xml.sax.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.sax.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.sax.parse(source=StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.sax.parse(source=StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
xml.sax.parseString(x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.sax.parseString(x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
xml.sax.parseString(string=x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xml.sax.parseString(string=x) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
parser = xml.sax.make_parser()
|
parser = xml.sax.make_parser()
|
||||||
parser.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
parser.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
parser.parse(source=StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
parser.parse(source=StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
# You can make it vuln to both XXE and DTD retrieval by setting this flag
|
# You can make it vuln to both XXE and DTD retrieval by setting this flag
|
||||||
# see https://docs.python.org/3/library/xml.sax.handler.html#xml.sax.handler.feature_external_ges
|
# see https://docs.python.org/3/library/xml.sax.handler.html#xml.sax.handler.feature_external_ges
|
||||||
parser = xml.sax.make_parser()
|
parser = xml.sax.make_parser()
|
||||||
parser.setFeature(xml.sax.handler.feature_external_ges, True)
|
parser.setFeature(xml.sax.handler.feature_external_ges, True)
|
||||||
parser.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='DTD retrieval' vuln='Quadratic Blowup' vuln='XXE'
|
parser.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE'
|
||||||
|
|
||||||
parser = xml.sax.make_parser()
|
parser = xml.sax.make_parser()
|
||||||
parser.setFeature(xml.sax.handler.feature_external_ges, False)
|
parser.setFeature(xml.sax.handler.feature_external_ges, False)
|
||||||
parser.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
parser.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
# Forward Type Tracking test
|
# Forward Type Tracking test
|
||||||
def func(cond):
|
def func(cond):
|
||||||
parser = xml.sax.make_parser()
|
parser = xml.sax.make_parser()
|
||||||
if cond:
|
if cond:
|
||||||
parser.setFeature(xml.sax.handler.feature_external_ges, True)
|
parser.setFeature(xml.sax.handler.feature_external_ges, True)
|
||||||
parser.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='DTD retrieval' vuln='Quadratic Blowup' vuln='XXE'
|
parser.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE'
|
||||||
else:
|
else:
|
||||||
parser.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
parser.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
# make it vuln, then making it safe
|
# make it vuln, then making it safe
|
||||||
# a bit of an edge-case, but is nice to be able to handle.
|
# a bit of an edge-case, but is nice to be able to handle.
|
||||||
parser = xml.sax.make_parser()
|
parser = xml.sax.make_parser()
|
||||||
parser.setFeature(xml.sax.handler.feature_external_ges, True)
|
parser.setFeature(xml.sax.handler.feature_external_ges, True)
|
||||||
parser.setFeature(xml.sax.handler.feature_external_ges, False)
|
parser.setFeature(xml.sax.handler.feature_external_ges, False)
|
||||||
parser.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='Quadratic Blowup'
|
parser.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|
||||||
def check_conditional_assignment(cond):
|
def check_conditional_assignment(cond):
|
||||||
parser = xml.sax.make_parser()
|
parser = xml.sax.make_parser()
|
||||||
@@ -52,7 +52,7 @@ def check_conditional_assignment(cond):
|
|||||||
parser.setFeature(xml.sax.handler.feature_external_ges, True)
|
parser.setFeature(xml.sax.handler.feature_external_ges, True)
|
||||||
else:
|
else:
|
||||||
parser.setFeature(xml.sax.handler.feature_external_ges, False)
|
parser.setFeature(xml.sax.handler.feature_external_ges, False)
|
||||||
parser.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='DTD retrieval' vuln='Quadratic Blowup' vuln='XXE'
|
parser.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE'
|
||||||
|
|
||||||
def check_conditional_assignment2(cond):
|
def check_conditional_assignment2(cond):
|
||||||
parser = xml.sax.make_parser()
|
parser = xml.sax.make_parser()
|
||||||
@@ -61,4 +61,4 @@ def check_conditional_assignment2(cond):
|
|||||||
else:
|
else:
|
||||||
flag_value = False
|
flag_value = False
|
||||||
parser.setFeature(xml.sax.handler.feature_external_ges, flag_value)
|
parser.setFeature(xml.sax.handler.feature_external_ges, flag_value)
|
||||||
parser.parse(StringIO(x)) # $ input=StringIO(..) vuln='Billion Laughs' vuln='DTD retrieval' vuln='Quadratic Blowup' vuln='XXE'
|
parser.parse(StringIO(x)) # $ xmlInput=StringIO(..) xmlVuln='Billion Laughs' xmlVuln='DTD retrieval' xmlVuln='Quadratic Blowup' xmlVuln='XXE'
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import xmltodict
|
|||||||
|
|
||||||
x = "some xml"
|
x = "some xml"
|
||||||
|
|
||||||
xmltodict.parse(x) # $ input=x
|
xmltodict.parse(x) # $ xmlInput=x
|
||||||
xmltodict.parse(xml_input=x) # $ input=x
|
xmltodict.parse(xml_input=x) # $ xmlInput=x
|
||||||
|
|
||||||
xmltodict.parse(x, disable_entities=False) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
xmltodict.parse(x, disable_entities=False) # $ xmlInput=x xmlVuln='Billion Laughs' xmlVuln='Quadratic Blowup'
|
||||||
|
|||||||
@@ -539,3 +539,30 @@ class HttpClientRequestTest extends InlineExpectationsTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class XmlParsingTest extends InlineExpectationsTest {
|
||||||
|
XmlParsingTest() { this = "XmlParsingTest" }
|
||||||
|
|
||||||
|
override string getARelevantTag() { result in ["xmlInput", "xmlVuln"] }
|
||||||
|
|
||||||
|
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||||
|
exists(location.getFile().getRelativePath()) and
|
||||||
|
exists(XML::XMLParsing parsing |
|
||||||
|
exists(DataFlow::Node input |
|
||||||
|
input = parsing.getAnInput() and
|
||||||
|
location = input.getLocation() and
|
||||||
|
element = input.toString() and
|
||||||
|
value = prettyNodeForInlineTest(input) and
|
||||||
|
tag = "xmlInput"
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(XML::XMLParsingVulnerabilityKind kind |
|
||||||
|
parsing.vulnerableTo(kind) and
|
||||||
|
location = parsing.getLocation() and
|
||||||
|
element = parsing.toString() and
|
||||||
|
value = "'" + kind + "'" and
|
||||||
|
tag = "xmlVuln"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user