mirror of
https://github.com/github/codeql.git
synced 2025-12-20 10:46:30 +01:00
Python: Delete XmlEntityInjection.ql
Kept the test of SimpleXmlRpcServer, and kept the qhelp so it can be used to write the new qhelp files
This commit is contained in:
committed by
Rasmus Wriedt Larsen
parent
769f5691d0
commit
c365337867
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE dt [
|
||||
<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
|
||||
<test>&xxe;</test>
|
||||
@@ -1,25 +0,0 @@
|
||||
from flask import request, Flask
|
||||
import lxml.etree
|
||||
import xml.etree.ElementTree
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# BAD
|
||||
@app.route("/bad")
|
||||
def bad():
|
||||
xml_content = request.args['xml_content']
|
||||
|
||||
parser = lxml.etree.XMLParser()
|
||||
parsed_xml = xml.etree.ElementTree.fromstring(xml_content, parser=parser)
|
||||
|
||||
return parsed_xml.text
|
||||
|
||||
# GOOD
|
||||
@app.route("/good")
|
||||
def good():
|
||||
xml_content = request.args['xml_content']
|
||||
|
||||
parser = lxml.etree.XMLParser(resolve_entities=False)
|
||||
parsed_xml = xml.etree.ElementTree.fromstring(xml_content, parser=parser)
|
||||
|
||||
return parsed_xml.text
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* @name XML Entity injection
|
||||
* @description User input should not be parsed allowing the injection of entities.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @id py/xml-entity-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-611
|
||||
* external/cwe/cwe-776
|
||||
* external/cwe/cwe-827
|
||||
*/
|
||||
|
||||
// determine precision above
|
||||
import python
|
||||
import experimental.semmle.python.security.dataflow.XmlEntityInjection
|
||||
import DataFlow::PathGraph
|
||||
|
||||
from
|
||||
XmlEntityInjection::XmlEntityInjectionConfiguration config, DataFlow::PathNode source,
|
||||
DataFlow::PathNode sink, string kinds
|
||||
where
|
||||
config.hasFlowPath(source, sink) and
|
||||
kinds =
|
||||
strictconcat(string kind |
|
||||
kind = sink.getNode().(XmlEntityInjection::Sink).getVulnerableKind()
|
||||
|
|
||||
kind, ", "
|
||||
)
|
||||
select sink.getNode(), source, sink,
|
||||
"$@ XML input is constructed from a $@ and is vulnerable to: " + kinds + ".", sink.getNode(),
|
||||
"This", source.getNode(), "user-provided value"
|
||||
@@ -1,28 +0,0 @@
|
||||
import python
|
||||
import experimental.semmle.python.Concepts
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import semmle.python.dataflow.new.TaintTracking
|
||||
import semmle.python.dataflow.new.RemoteFlowSources
|
||||
import semmle.python.dataflow.new.BarrierGuards
|
||||
|
||||
module XmlEntityInjection {
|
||||
import XmlEntityInjectionCustomizations::XmlEntityInjection
|
||||
|
||||
class XmlEntityInjectionConfiguration extends TaintTracking::Configuration {
|
||||
XmlEntityInjectionConfiguration() { this = "XmlEntityInjectionConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source instanceof RemoteFlowSourceAsSource
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
|
||||
|
||||
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
|
||||
guard instanceof SanitizerGuard
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
any(AdditionalTaintStep s).step(nodeFrom, nodeTo)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting
|
||||
* "ldap injection"
|
||||
* vulnerabilities, as well as extension points for adding your own.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import experimental.semmle.python.Concepts
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.dataflow.new.BarrierGuards
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
/**
|
||||
* Provides default sources, sinks and sanitizers for detecting "xml injection"
|
||||
* vulnerabilities, as well as extension points for adding your own.
|
||||
*/
|
||||
module XmlEntityInjection {
|
||||
/**
|
||||
* A data flow source for "xml injection" vulnerabilities.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A data flow sink for "xml injection" vulnerabilities.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
|
||||
|
||||
/**
|
||||
* A unit class for adding additional taint steps.
|
||||
*
|
||||
* Extend this class to add additional taint steps that should apply to `XmlEntityInjection`
|
||||
* taint configuration.
|
||||
*/
|
||||
class AdditionalTaintStep extends Unit {
|
||||
/**
|
||||
* Holds if the step from `nodeFrom` to `nodeTo` should be considered a taint
|
||||
* step for `XmlEntityInjection` configuration.
|
||||
*/
|
||||
abstract predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* An input to a direct XML parsing function, considered as a flow sink.
|
||||
*
|
||||
* See `XML::XMLParsing`.
|
||||
*/
|
||||
class XMLParsingInputAsSink extends Sink {
|
||||
ExperimentalXML::XMLParsing xmlParsing;
|
||||
|
||||
XMLParsingInputAsSink() { this = xmlParsing.getAnInput() }
|
||||
|
||||
override string getVulnerableKind() { xmlParsing.vulnerableTo(result) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A source of remote user input, considered as a flow source.
|
||||
*/
|
||||
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
|
||||
|
||||
/**
|
||||
* A comparison with a constant string, considered as a sanitizer-guard.
|
||||
*/
|
||||
class StringConstCompareAsSanitizerGuard extends SanitizerGuard, StringConstCompare { }
|
||||
|
||||
/**
|
||||
* A taint step for `io`'s `StringIO` and `BytesIO` methods.
|
||||
*/
|
||||
class IoAdditionalTaintStep extends AdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
exists(DataFlow::CallCfgNode ioCalls |
|
||||
ioCalls = API::moduleImport("io").getMember(["StringIO", "BytesIO"]).getACall() and
|
||||
nodeFrom = ioCalls.getArg(0) and
|
||||
nodeTo = ioCalls
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
edges
|
||||
| test.py:8:19:8:25 | ControlFlowNode for request | test.py:8:19:8:30 | ControlFlowNode for Attribute |
|
||||
| test.py:8:19:8:30 | ControlFlowNode for Attribute | test.py:8:19:8:45 | ControlFlowNode for Subscript |
|
||||
| test.py:8:19:8:45 | ControlFlowNode for Subscript | test.py:9:34:9:44 | ControlFlowNode for xml_content |
|
||||
| test.py:13:19:13:25 | ControlFlowNode for request | test.py:13:19:13:30 | ControlFlowNode for Attribute |
|
||||
| test.py:13:19:13:30 | ControlFlowNode for Attribute | test.py:13:19:13:45 | ControlFlowNode for Subscript |
|
||||
| test.py:13:19:13:45 | ControlFlowNode for Subscript | test.py:15:34:15:44 | ControlFlowNode for xml_content |
|
||||
| test.py:19:19:19:25 | ControlFlowNode for request | test.py:19:19:19:30 | ControlFlowNode for Attribute |
|
||||
| test.py:19:19:19:30 | ControlFlowNode for Attribute | test.py:19:19:19:45 | ControlFlowNode for Subscript |
|
||||
| test.py:19:19:19:45 | ControlFlowNode for Subscript | test.py:30:34:30:44 | ControlFlowNode for xml_content |
|
||||
nodes
|
||||
| test.py:8:19:8:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test.py:8:19:8:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test.py:8:19:8:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:9:34:9:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content |
|
||||
| test.py:13:19:13:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test.py:13:19:13:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test.py:13:19:13:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:15:34:15:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content |
|
||||
| test.py:19:19:19:25 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
|
||||
| test.py:19:19:19:30 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
|
||||
| test.py:19:19:19:45 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:30:34:30:44 | ControlFlowNode for xml_content | semmle.label | ControlFlowNode for xml_content |
|
||||
subpaths
|
||||
#select
|
||||
| test.py:9:34:9:44 | ControlFlowNode for xml_content | test.py:8:19:8:25 | ControlFlowNode for request | test.py:9:34:9:44 | ControlFlowNode for xml_content | $@ XML input is constructed from a $@ and is vulnerable to: XXE. | test.py:9:34:9:44 | ControlFlowNode for xml_content | This | test.py:8:19:8:25 | ControlFlowNode for request | user-provided value |
|
||||
| test.py:30:34:30:44 | ControlFlowNode for xml_content | test.py:19:19:19:25 | ControlFlowNode for request | test.py:30:34:30:44 | ControlFlowNode for xml_content | $@ XML input is constructed from a $@ and is vulnerable to: Billion Laughs, DTD retrieval, Quadratic Blowup, XXE. | test.py:30:34:30:44 | ControlFlowNode for xml_content | This | test.py:19:19:19:25 | ControlFlowNode for request | user-provided value |
|
||||
@@ -1 +0,0 @@
|
||||
experimental/Security/CWE-611/XmlEntityInjection.ql
|
||||
@@ -1,30 +0,0 @@
|
||||
from flask import Flask, request
|
||||
import lxml.etree
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/vuln-handler")
|
||||
def vuln_handler():
|
||||
xml_content = request.args['xml_content']
|
||||
return lxml.etree.fromstring(xml_content).text
|
||||
|
||||
@app.route("/safe-handler")
|
||||
def safe_handler():
|
||||
xml_content = request.args['xml_content']
|
||||
parser = lxml.etree.XMLParser(resolve_entities=False)
|
||||
return lxml.etree.fromstring(xml_content, parser=parser).text
|
||||
|
||||
@app.route("/super-vuln-handler")
|
||||
def super_vuln_handler():
|
||||
xml_content = request.args['xml_content']
|
||||
parser = lxml.etree.XMLParser(
|
||||
# allows XXE
|
||||
resolve_entities=True,
|
||||
# allows remote XXE
|
||||
no_network=False,
|
||||
# together with `no_network=False`, allows DTD-retrival
|
||||
load_dtd=True,
|
||||
# allows DoS attacks
|
||||
huge_tree=True,
|
||||
)
|
||||
return lxml.etree.fromstring(xml_content, parser=parser).text
|
||||
Reference in New Issue
Block a user