Python: XML: Expose vuln kind on sink

This commit is contained in:
Rasmus Wriedt Larsen
2022-03-01 17:15:19 +01:00
committed by Rasmus Wriedt Larsen
parent 500e0aced6
commit ee23c05489
3 changed files with 26 additions and 55 deletions

View File

@@ -15,8 +15,12 @@ import python
import experimental.semmle.python.security.dataflow.XmlEntityInjection
import DataFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, string kind
where XmlEntityInjection::xmlEntityInjectionVulnerable(source, sink, kind)
from
XmlEntityInjection::XmlEntityInjectionConfiguration config, DataFlow::PathNode source,
DataFlow::PathNode sink, string kind
where
config.hasFlowPath(source, sink) and
kind = sink.getNode().(XmlEntityInjection::Sink).getVulnerableKind()
select sink.getNode(), source, sink,
"$@ XML input is constructed from a $@ and is vulnerable to " + kind + ".", sink.getNode(),
"This", source.getNode(), "user-provided value"

View File

@@ -25,22 +25,4 @@ module XmlEntityInjection {
any(AdditionalTaintStep s).step(nodeFrom, nodeTo)
}
}
private import DataFlow::PathGraph
/** Holds if there is an XML injection from `source` to `sink` */
predicate xmlEntityInjection(DataFlow::PathNode source, DataFlow::PathNode sink) {
any(XmlEntityInjectionConfiguration x).hasFlowPath(source, sink)
}
/** Holds if there is an XML injection from `source` to `sink` vulnerable to `kind` */
predicate xmlEntityInjectionVulnerable(
DataFlow::PathNode source, DataFlow::PathNode sink, string kind
) {
xmlEntityInjection(source, sink) and
(
xmlParsingInputAsVulnerableSink(sink.getNode(), kind) or
xmlParserInputAsVulnerableSink(sink.getNode(), kind)
)
}
}

View File

@@ -24,7 +24,10 @@ module XmlEntityInjection {
/**
* A data flow sink for "xml injection" vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
abstract class Sink extends DataFlow::Node {
/** Gets the kind of XML injection that this sink is vulnerable to. */
abstract string getVulnerableKind();
}
/**
* A sanitizer guard for "xml injection" vulnerabilities.
@@ -46,54 +49,36 @@ module XmlEntityInjection {
}
/**
* A data flow sink for XML parsing libraries.
* An input to a direct XML parsing function, considered as a flow sink.
*
* See `XML::XMLParsing`.
*/
abstract class XMLParsingSink extends Sink { }
class XMLParsingInputAsSink extends Sink {
XML::XMLParsing xmlParsing;
XMLParsingInputAsSink() { this = xmlParsing.getAnInput() }
override string getVulnerableKind() { xmlParsing.vulnerable(result) }
}
/**
* A data flow sink for XML parsers.
* An input to an XML parser, considered as a flow sink.
*
* See `XML::XMLParser`
*/
abstract class XMLParserSink extends Sink { }
class XMLParserInputAsSink extends Sink {
XML::XMLParser xmlParser;
XMLParserInputAsSink() { this = xmlParser.getAnInput() }
override string getVulnerableKind() { xmlParser.vulnerable(result) }
}
/**
* A source of remote user input, considered as a flow source.
*/
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
/**
* An xml parsing operation, considered as a flow sink.
*/
class XMLParsingInputAsSink extends XMLParsingSink {
XMLParsingInputAsSink() { this = any(XML::XMLParsing xmlParsing).getAnInput() }
}
/**
* An xml parsing operation vulnerable to `kind`.
*/
predicate xmlParsingInputAsVulnerableSink(DataFlow::Node sink, string kind) {
exists(XML::XMLParsing xmlParsing |
sink = xmlParsing.getAnInput() and xmlParsing.vulnerable(kind)
)
}
/**
* An xml parser operation, considered as a flow sink.
*/
class XMLParserInputAsSink extends XMLParserSink {
XMLParserInputAsSink() { this = any(XML::XMLParser xmlParser).getAnInput() }
}
/**
* An xml parser operation vulnerable to `kind`.
*/
predicate xmlParserInputAsVulnerableSink(DataFlow::Node sink, string kind) {
exists(XML::XMLParser xmlParser | sink = xmlParser.getAnInput() and xmlParser.vulnerable(kind))
}
/**
* A comparison with a constant string, considered as a sanitizer-guard.
*/