mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Python: Support feed method of lxml/xml.etree Parsers
This commit is contained in:
@@ -79,6 +79,28 @@ private module Xml {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `feed` method of an `xml.etree` parser.
|
||||
*/
|
||||
private class XMLEtreeParserFeedCall extends DataFlow::CallCfgNode, XML::XMLParsing::Range {
|
||||
XMLEtreeParserFeedCall() {
|
||||
this =
|
||||
API::moduleImport("xml")
|
||||
.getMember("etree")
|
||||
.getMember("ElementTree")
|
||||
.getMember("XMLParser")
|
||||
.getReturn()
|
||||
.getMember("feed")
|
||||
.getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
|
||||
|
||||
override predicate vulnerable(XML::XMLVulnerabilityKind kind) {
|
||||
kind.isBillionLaughs() or kind.isQuadraticBlowup()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `setFeature` method on a XML sax parser.
|
||||
*
|
||||
@@ -322,6 +344,7 @@ private module Xml {
|
||||
}
|
||||
|
||||
override predicate vulnerable(XML::XMLVulnerabilityKind kind) {
|
||||
// TODO: This should be done with type-tracking
|
||||
exists(XML::XMLParser xmlParser |
|
||||
xmlParser = this.getArgByName("parser").getALocalSource() and xmlParser.vulnerable(kind)
|
||||
)
|
||||
@@ -330,6 +353,33 @@ private module Xml {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to the `feed` method of an `lxml.etree` parser.
|
||||
*/
|
||||
private class LXMLEtreeParserFeedCall extends DataFlow::MethodCallNode, XML::XMLParsing::Range {
|
||||
LXMLEtreeParserFeedCall() {
|
||||
exists(API::Node parserInstance |
|
||||
parserInstance =
|
||||
API::moduleImport("lxml").getMember("etree").getMember("XMLParser").getReturn()
|
||||
or
|
||||
parserInstance =
|
||||
API::moduleImport("lxml").getMember("etree").getMember("get_default_parser").getReturn()
|
||||
|
|
||||
this = parserInstance.getMember("feed").getACall()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
|
||||
|
||||
override predicate vulnerable(XML::XMLVulnerabilityKind kind) {
|
||||
// TODO: This should be done with type-tracking
|
||||
exists(XML::XMLParser xmlParser |
|
||||
xmlParser = this.getObject().getALocalSource() and
|
||||
xmlParser.vulnerable(kind)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a call to `xmltodict.parse`.
|
||||
*
|
||||
|
||||
@@ -26,6 +26,12 @@ lxml.etree.fromstring(x, parser=parser) # $ input=x vuln='XXE'
|
||||
parser = lxml.etree.get_default_parser()
|
||||
lxml.etree.fromstring(x, parser=parser) # $ input=x vuln='XXE'
|
||||
|
||||
# manual use of feed method
|
||||
parser = lxml.etree.XMLParser()
|
||||
parser.feed(x) # $ input=x vuln='XXE'
|
||||
parser.feed(data=x) # $ input=x vuln='XXE'
|
||||
parser.close()
|
||||
|
||||
# XXE-safe
|
||||
parser = lxml.etree.XMLParser(resolve_entities=False)
|
||||
lxml.etree.fromstring(x, parser=parser) # $ input=x
|
||||
|
||||
@@ -27,6 +27,12 @@ xml.etree.ElementTree.iterparse(source=StringIO(x)) # $ input=StringIO(..) vuln=
|
||||
parser = xml.etree.ElementTree.XMLParser()
|
||||
xml.etree.ElementTree.fromstring(x, parser=parser) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
||||
|
||||
# manual use of feed method
|
||||
parser = xml.etree.ElementTree.XMLParser()
|
||||
parser.feed(x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
||||
parser.feed(data=x) # $ input=x vuln='Billion Laughs' vuln='Quadratic Blowup'
|
||||
parser.close()
|
||||
|
||||
# note: it's technically possible to use the thing wrapper func `fromstring` with an
|
||||
# `lxml` parser, and thereby change what vulnerabilities you are exposed to.. but it
|
||||
# seems very unlikely that anyone would do this, so we have intentionally not added any
|
||||
|
||||
Reference in New Issue
Block a user