diff --git a/python/ql/src/experimental/Security/CWE-643/xpath.qhelp b/python/ql/src/experimental/Security/CWE-643/XpathInjection.qhelp similarity index 100% rename from python/ql/src/experimental/Security/CWE-643/xpath.qhelp rename to python/ql/src/experimental/Security/CWE-643/XpathInjection.qhelp diff --git a/python/ql/src/experimental/Security/CWE-643/XpathInjection.ql b/python/ql/src/experimental/Security/CWE-643/XpathInjection.ql new file mode 100644 index 000000000000..67b4741f6107 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-643/XpathInjection.ql @@ -0,0 +1,33 @@ +/** + * @name XPath query built from user-controlled sources + * @description Building a XPath query from user-controlled sources is vulnerable to insertion of + * malicious Xpath code by the user. + * @kind path-problem + * @problem.severity error + * @precision high + * @id py/xpath-injection + * @tags security + * external/cwe/cwe-643 + */ + +private import python +private import semmle.python.Concepts +private import semmle.python.dataflow.new.TaintTracking +private import semmle.python.Concepts +private import semmle.python.ApiGraphs +private import semmle.python.dataflow.new.RemoteFlowSources +private import semmle.python.dataflow.new.BarrierGuards +import XpathInjection::XpathInjection +import DataFlow::PathGraph + +class XpathInjectionConfiguration extends TaintTracking::Configuration { + XpathInjectionConfiguration() { this = "PathNotNormalizedConfiguration" } + + override predicate isSource(DataFlow::Node source) { source instanceof Source } + + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } +} + +from XpathInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink, source, sink, "This Xpath query depends on $@.", source, "a user-provided value" diff --git a/python/ql/src/experimental/Security/CWE-643/XpathInjection.qll b/python/ql/src/experimental/Security/CWE-643/XpathInjection.qll new file mode 100644 index 000000000000..e0a0815666ac --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-643/XpathInjection.qll @@ -0,0 +1,35 @@ +/** + * Provides a taint-tracking configuration for detecting "Xpath Injection" vulnerabilities. + * + * Note, for performance reasons: only import this file if + * `XpathInjection::Configuration` is needed, otherwise + * `XpathInjectionCustomizations` should be imported instead. + */ + +private import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking + +/** + * Provides a taint-tracking configuration for detecting "Xpath Injection" vulnerabilities. + */ +module XpathInjection { + import XpathInjectionCustomizations::XpathInjection + + /** + * A taint-tracking configuration for detecting "Xpath Injection" vulnerabilities. + */ + class Configuration extends TaintTracking::Configuration { + Configuration() { this = "Xpath Injection" } + + override predicate isSource(DataFlow::Node source) { source instanceof Source } + + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } + + override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { + guard instanceof SanitizerGuard + } + } +} diff --git a/python/ql/src/experimental/Security/CWE-643/XpathInjectionCustomizations.qll b/python/ql/src/experimental/Security/CWE-643/XpathInjectionCustomizations.qll new file mode 100644 index 000000000000..4a939253636b --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-643/XpathInjectionCustomizations.qll @@ -0,0 +1,105 @@ +/** + * Provides class and predicates to track external data that + * may represent malicious xpath query objects. + * + * This module is intended to be imported into a taint-tracking query. + */ + +private import python +private import semmle.python.Concepts +private import semmle.python.dataflow.new.TaintTracking +private import semmle.python.Concepts +private import semmle.python.ApiGraphs +private import semmle.python.dataflow.new.RemoteFlowSources +private import semmle.python.dataflow.new.BarrierGuards + +/** Models Xpath Injection related classes and functions */ +module XpathInjection { + /** + * A data flow source for "XPath injection" vulnerabilities. + */ + abstract class Source extends DataFlow::Node { } + + /** + * A data flow sink for "XPath injection" vulnerabilities. + */ + abstract class Sink extends DataFlow::Node { } + + /** + * A sanitizer for "XPath injection" vulnerabilities. + */ + abstract class Sanitizer extends DataFlow::Node { } + + /** + * A sanitizer guard for "XPath injection" vulnerabilities. + */ + abstract class SanitizerGuard extends DataFlow::BarrierGuard { } + + /** + * A source of remote user input, considered as a flow source. + */ + class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { } + + /** Returns an API node referring to `lxml.etree` */ + API::Node etree() { result = API::moduleImport("lxml").getMember("etree") } + + /** Returns an API node referring to `lxml.etree` */ + API::Node etreeFromString() { result = etree().getMember("fromstring") } + + /** Returns an API node referring to `lxml.etree.parse` */ + API::Node etreeParse() { result = etree().getMember("parse") } + + /** Returns an API node referring to `lxml.etree.parse` */ + API::Node libxml2parseFile() { result = API::moduleImport("libxml2").getMember("parseFile") } + + /** + * A Sink representing an argument to `etree.XPath` or `etree.ETXPath` call. + * + * from lxml import etree + * root = etree.XML("") + * find_text = etree.XPath("`sink`") + * find_text = etree.ETXPath("`sink`") + */ + private class EtreeXpathArgument extends Sink { + EtreeXpathArgument() { this = etree().getMember(["XPath", "ETXPath"]).getACall().getArg(0) } + } + + /** + * A Sink representing an argument to the `etree.XPath` call. + * + * from lxml import etree + * root = etree.fromstring(file(XML_DB).read(), XMLParser()) + * find_text = root.xpath("`sink`") + */ + private class EtreeFromstringXpathArgument extends Sink { + EtreeFromstringXpathArgument() { + this = etreeFromString().getReturn().getMember("xpath").getACall().getArg(0) + } + } + + /** + * A Sink representing an argument to the `xpath` call to a parsed xml document. + * + * from lxml import etree + * from io import StringIO + * f = StringIO('') + * tree = etree.parse(f) + * r = tree.xpath('`sink`') + */ + private class ParseXpathArgument extends Sink { + ParseXpathArgument() { this = etreeParse().getReturn().getMember("xpath").getACall().getArg(0) } + } + + /** + * A Sink representing an argument to the `xpathEval` call to a parsed libxml2 document. + * + * import libxml2 + * tree = libxml2.parseFile("file.xml") + * r = tree.xpathEval('`sink`') + */ + private class ParseFileXpathEvalArgument extends Sink { + ParseFileXpathEvalArgument() { + this = libxml2parseFile().getReturn().getMember("xpathEval").getACall().getArg(0) + } + } +} diff --git a/python/ql/src/experimental/Security/CWE-643/xpath.ql b/python/ql/src/experimental/Security/CWE-643/xpath.ql deleted file mode 100644 index 15720c408eeb..000000000000 --- a/python/ql/src/experimental/Security/CWE-643/xpath.ql +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @name XPath query built from user-controlled sources - * @description Building a XPath query from user-controlled sources is vulnerable to insertion of - * malicious Xpath code by the user. - * @kind path-problem - * @problem.severity error - * @precision high - * @id py/xpath-injection - * @tags security - * external/cwe/cwe-643 - */ - -import python -import semmle.python.security.Paths -import semmle.python.security.strings.Untrusted -/* Sources */ -import semmle.python.web.HttpRequest -/* Sinks */ -import experimental.semmle.python.security.injection.Xpath - -class XpathInjectionConfiguration extends TaintTracking::Configuration { - XpathInjectionConfiguration() { this = "Xpath injection configuration" } - - override predicate isSource(TaintTracking::Source source) { - source instanceof HttpRequestTaintSource - } - - override predicate isSink(TaintTracking::Sink sink) { - sink instanceof XpathInjection::XpathInjectionSink - } -} - -from XpathInjectionConfiguration config, TaintedPathSource src, TaintedPathSink sink -where config.hasFlowPath(src, sink) -select sink.getSink(), src, sink, "This Xpath query depends on $@.", src.getSource(), - "a user-provided value" diff --git a/python/ql/src/experimental/semmle/python/security/injection/Xpath.qll b/python/ql/src/experimental/semmle/python/security/injection/Xpath.qll deleted file mode 100644 index fa5c7647f1f0..000000000000 --- a/python/ql/src/experimental/semmle/python/security/injection/Xpath.qll +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Provides class and predicates to track external data that - * may represent malicious xpath query objects. - * - * This module is intended to be imported into a taint-tracking query - * to extend `TaintKind` and `TaintSink`. - */ - -import python -import semmle.python.dataflow.TaintTracking -import semmle.python.web.HttpRequest - -/** Models Xpath Injection related classes and functions */ -module XpathInjection { - /** Returns a class value which refers to `lxml.etree` */ - Value etree() { result = Value::named("lxml.etree") } - - /** Returns a class value which refers to `lxml.etree` */ - Value libxml2parseFile() { result = Value::named("libxml2.parseFile") } - - /** A generic taint sink that is vulnerable to Xpath injection. */ - abstract class XpathInjectionSink extends TaintSink { } - - /** - * A Sink representing an argument to the `etree.XPath` call. - * - * from lxml import etree - * root = etree.XML("") - * find_text = etree.XPath("`sink`") - */ - private class EtreeXpathArgument extends XpathInjectionSink { - override string toString() { result = "lxml.etree.XPath" } - - EtreeXpathArgument() { - exists(CallNode call | call.getFunction().(AttrNode).getObject("XPath").pointsTo(etree()) | - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - } - - /** - * A Sink representing an argument to the `etree.EtXpath` call. - * - * from lxml import etree - * root = etree.XML("") - * find_text = etree.EtXPath("`sink`") - */ - private class EtreeETXpathArgument extends XpathInjectionSink { - override string toString() { result = "lxml.etree.ETXpath" } - - EtreeETXpathArgument() { - exists(CallNode call | call.getFunction().(AttrNode).getObject("ETXPath").pointsTo(etree()) | - call.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - } - - /** - * A Sink representing an argument to the `xpath` call to a parsed xml document. - * - * from lxml import etree - * from io import StringIO - * f = StringIO('') - * tree = etree.parse(f) - * r = tree.xpath('`sink`') - */ - private class ParseXpathArgument extends XpathInjectionSink { - override string toString() { result = "lxml.etree.parse.xpath" } - - ParseXpathArgument() { - exists( - CallNode parseCall, CallNode xpathCall, ControlFlowNode obj, Variable var, AssignStmt assign - | - parseCall.getFunction().(AttrNode).getObject("parse").pointsTo(etree()) and - assign.getValue().(Call).getAFlowNode() = parseCall and - xpathCall.getFunction().(AttrNode).getObject("xpath") = obj and - var.getAUse() = obj and - assign.getATarget() = var.getAStore() and - xpathCall.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - } - - /** - * A Sink representing an argument to the `xpathEval` call to a parsed libxml2 document. - * - * import libxml2 - * tree = libxml2.parseFile("file.xml") - * r = tree.xpathEval('`sink`') - */ - private class ParseFileXpathEvalArgument extends XpathInjectionSink { - override string toString() { result = "libxml2.parseFile.xpathEval" } - - ParseFileXpathEvalArgument() { - exists( - CallNode parseCall, CallNode xpathCall, ControlFlowNode obj, Variable var, AssignStmt assign - | - parseCall.getFunction().(AttrNode).pointsTo(libxml2parseFile()) and - assign.getValue().(Call).getAFlowNode() = parseCall and - xpathCall.getFunction().(AttrNode).getObject("xpathEval") = obj and - var.getAUse() = obj and - assign.getATarget() = var.getAStore() and - xpathCall.getArg(0) = this - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - } -} diff --git a/python/ql/test/experimental/query-tests/Security/CWE-643/XpathInjection.expected b/python/ql/test/experimental/query-tests/Security/CWE-643/XpathInjection.expected new file mode 100644 index 000000000000..681474528227 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-643/XpathInjection.expected @@ -0,0 +1,74 @@ +edges +| xpathBad.py:9:7:9:13 | ControlFlowNode for request | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | +| xpathBad.py:9:7:9:13 | ControlFlowNode for request | xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | +| xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | +| xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | +| xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | +| xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | +| xpathFlow.py:11:18:11:24 | ControlFlowNode for request | xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | +| xpathFlow.py:11:18:11:24 | ControlFlowNode for request | xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | +| xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | +| xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | +| xpathFlow.py:20:18:20:24 | ControlFlowNode for request | xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | +| xpathFlow.py:20:18:20:24 | ControlFlowNode for request | xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | +| xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | +| xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | +| xpathFlow.py:30:18:30:24 | ControlFlowNode for request | xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | +| xpathFlow.py:30:18:30:24 | ControlFlowNode for request | xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | +| xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | +| xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | +| xpathFlow.py:39:18:39:24 | ControlFlowNode for request | xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | +| xpathFlow.py:39:18:39:24 | ControlFlowNode for request | xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | +| xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | +| xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | +| xpathFlow.py:47:18:47:24 | ControlFlowNode for request | xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | +| xpathFlow.py:47:18:47:24 | ControlFlowNode for request | xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | +| xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | +| xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | +nodes +| xpathBad.py:9:7:9:13 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathBad.py:9:7:9:13 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathBad.py:10:13:10:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| xpathBad.py:10:13:10:32 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | +| xpathFlow.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:20:18:20:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:20:18:20:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:20:18:20:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:30:18:30:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:30:18:30:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:30:18:30:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:39:18:39:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:39:18:39:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:39:18:39:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:47:18:47:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:47:18:47:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:47:18:47:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +| xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | semmle.label | ControlFlowNode for xpathQuery | +subpaths +#select +| xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | xpathBad.py:9:7:9:13 | ControlFlowNode for request | xpathBad.py:13:20:13:43 | ControlFlowNode for BinaryExpr | This Xpath query depends on $@. | xpathBad.py:9:7:9:13 | ControlFlowNode for request | a user-provided value | +| xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | xpathFlow.py:14:20:14:29 | ControlFlowNode for xpathQuery | This Xpath query depends on $@. | xpathFlow.py:11:18:11:24 | ControlFlowNode for request | a user-provided value | +| xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | xpathFlow.py:23:29:23:38 | ControlFlowNode for xpathQuery | This Xpath query depends on $@. | xpathFlow.py:20:18:20:24 | ControlFlowNode for request | a user-provided value | +| xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | xpathFlow.py:30:18:30:24 | ControlFlowNode for request | xpathFlow.py:32:29:32:38 | ControlFlowNode for xpathQuery | This Xpath query depends on $@. | xpathFlow.py:30:18:30:24 | ControlFlowNode for request | a user-provided value | +| xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | xpathFlow.py:39:18:39:24 | ControlFlowNode for request | xpathFlow.py:41:31:41:40 | ControlFlowNode for xpathQuery | This Xpath query depends on $@. | xpathFlow.py:39:18:39:24 | ControlFlowNode for request | a user-provided value | +| xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | xpathFlow.py:47:18:47:24 | ControlFlowNode for request | xpathFlow.py:49:29:49:38 | ControlFlowNode for xpathQuery | This Xpath query depends on $@. | xpathFlow.py:47:18:47:24 | ControlFlowNode for request | a user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-643/XpathInjection.qlref b/python/ql/test/experimental/query-tests/Security/CWE-643/XpathInjection.qlref new file mode 100644 index 000000000000..2c4f25a5b9aa --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-643/XpathInjection.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-643/XpathInjection.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-643/options b/python/ql/test/experimental/query-tests/Security/CWE-643/options deleted file mode 100644 index 2f457593f2ed..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-643/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=3 -p ../../../../query-tests/Security/lib/ diff --git a/python/ql/test/experimental/query-tests/Security/CWE-643/xpath.expected b/python/ql/test/experimental/query-tests/Security/CWE-643/xpath.expected deleted file mode 100644 index 2f32859d6a98..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-643/xpath.expected +++ /dev/null @@ -1,38 +0,0 @@ -edges -| xpathBad.py:9:7:9:13 | django.request.HttpRequest | xpathBad.py:10:13:10:19 | django.request.HttpRequest | -| xpathBad.py:9:7:9:13 | django.request.HttpRequest | xpathBad.py:10:13:10:19 | django.request.HttpRequest | -| xpathBad.py:10:13:10:19 | django.request.HttpRequest | xpathBad.py:10:13:10:23 | django.http.request.QueryDict | -| xpathBad.py:10:13:10:19 | django.request.HttpRequest | xpathBad.py:10:13:10:23 | django.http.request.QueryDict | -| xpathBad.py:10:13:10:23 | django.http.request.QueryDict | xpathBad.py:10:13:10:32 | externally controlled string | -| xpathBad.py:10:13:10:23 | django.http.request.QueryDict | xpathBad.py:10:13:10:32 | externally controlled string | -| xpathBad.py:10:13:10:32 | externally controlled string | xpathBad.py:13:39:13:43 | externally controlled string | -| xpathBad.py:10:13:10:32 | externally controlled string | xpathBad.py:13:39:13:43 | externally controlled string | -| xpathBad.py:13:39:13:43 | externally controlled string | xpathBad.py:13:20:13:43 | externally controlled string | -| xpathBad.py:13:39:13:43 | externally controlled string | xpathBad.py:13:20:13:43 | externally controlled string | -| xpathFlow.py:11:18:11:29 | dict of externally controlled string | xpathFlow.py:11:18:11:44 | externally controlled string | -| xpathFlow.py:11:18:11:29 | dict of externally controlled string | xpathFlow.py:11:18:11:44 | externally controlled string | -| xpathFlow.py:11:18:11:44 | externally controlled string | xpathFlow.py:14:20:14:29 | externally controlled string | -| xpathFlow.py:11:18:11:44 | externally controlled string | xpathFlow.py:14:20:14:29 | externally controlled string | -| xpathFlow.py:20:18:20:29 | dict of externally controlled string | xpathFlow.py:20:18:20:44 | externally controlled string | -| xpathFlow.py:20:18:20:29 | dict of externally controlled string | xpathFlow.py:20:18:20:44 | externally controlled string | -| xpathFlow.py:20:18:20:44 | externally controlled string | xpathFlow.py:23:29:23:38 | externally controlled string | -| xpathFlow.py:20:18:20:44 | externally controlled string | xpathFlow.py:23:29:23:38 | externally controlled string | -| xpathFlow.py:30:18:30:29 | dict of externally controlled string | xpathFlow.py:30:18:30:44 | externally controlled string | -| xpathFlow.py:30:18:30:29 | dict of externally controlled string | xpathFlow.py:30:18:30:44 | externally controlled string | -| xpathFlow.py:30:18:30:44 | externally controlled string | xpathFlow.py:32:29:32:38 | externally controlled string | -| xpathFlow.py:30:18:30:44 | externally controlled string | xpathFlow.py:32:29:32:38 | externally controlled string | -| xpathFlow.py:39:18:39:29 | dict of externally controlled string | xpathFlow.py:39:18:39:44 | externally controlled string | -| xpathFlow.py:39:18:39:29 | dict of externally controlled string | xpathFlow.py:39:18:39:44 | externally controlled string | -| xpathFlow.py:39:18:39:44 | externally controlled string | xpathFlow.py:41:31:41:40 | externally controlled string | -| xpathFlow.py:39:18:39:44 | externally controlled string | xpathFlow.py:41:31:41:40 | externally controlled string | -| xpathFlow.py:47:18:47:29 | dict of externally controlled string | xpathFlow.py:47:18:47:44 | externally controlled string | -| xpathFlow.py:47:18:47:29 | dict of externally controlled string | xpathFlow.py:47:18:47:44 | externally controlled string | -| xpathFlow.py:47:18:47:44 | externally controlled string | xpathFlow.py:49:29:49:38 | externally controlled string | -| xpathFlow.py:47:18:47:44 | externally controlled string | xpathFlow.py:49:29:49:38 | externally controlled string | -#select -| xpathBad.py:13:20:13:43 | BinaryExpr | xpathBad.py:9:7:9:13 | django.request.HttpRequest | xpathBad.py:13:20:13:43 | externally controlled string | This Xpath query depends on $@. | xpathBad.py:9:7:9:13 | request | a user-provided value | -| xpathFlow.py:14:20:14:29 | xpathQuery | xpathFlow.py:11:18:11:29 | dict of externally controlled string | xpathFlow.py:14:20:14:29 | externally controlled string | This Xpath query depends on $@. | xpathFlow.py:11:18:11:29 | Attribute | a user-provided value | -| xpathFlow.py:23:29:23:38 | xpathQuery | xpathFlow.py:20:18:20:29 | dict of externally controlled string | xpathFlow.py:23:29:23:38 | externally controlled string | This Xpath query depends on $@. | xpathFlow.py:20:18:20:29 | Attribute | a user-provided value | -| xpathFlow.py:32:29:32:38 | xpathQuery | xpathFlow.py:30:18:30:29 | dict of externally controlled string | xpathFlow.py:32:29:32:38 | externally controlled string | This Xpath query depends on $@. | xpathFlow.py:30:18:30:29 | Attribute | a user-provided value | -| xpathFlow.py:41:31:41:40 | xpathQuery | xpathFlow.py:39:18:39:29 | dict of externally controlled string | xpathFlow.py:41:31:41:40 | externally controlled string | This Xpath query depends on $@. | xpathFlow.py:39:18:39:29 | Attribute | a user-provided value | -| xpathFlow.py:49:29:49:38 | xpathQuery | xpathFlow.py:47:18:47:29 | dict of externally controlled string | xpathFlow.py:49:29:49:38 | externally controlled string | This Xpath query depends on $@. | xpathFlow.py:47:18:47:29 | Attribute | a user-provided value | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-643/xpath.qlref b/python/ql/test/experimental/query-tests/Security/CWE-643/xpath.qlref deleted file mode 100644 index b0940dcc0a5b..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-643/xpath.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE-643/xpath.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-643/xpathSinks.expected b/python/ql/test/experimental/query-tests/Security/CWE-643/xpathSinks.expected deleted file mode 100644 index c3bfec2fcafb..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-643/xpathSinks.expected +++ /dev/null @@ -1,12 +0,0 @@ -| xpath.py:8:20:8:29 | lxml.etree.parse.xpath | externally controlled string | -| xpath.py:13:29:13:38 | lxml.etree.XPath | externally controlled string | -| xpath.py:19:29:19:38 | lxml.etree.XPath | externally controlled string | -| xpath.py:25:38:25:46 | lxml.etree.ETXpath | externally controlled string | -| xpath.py:32:29:32:34 | libxml2.parseFile.xpathEval | externally controlled string | -| xpathBad.py:13:20:13:43 | lxml.etree.parse.xpath | externally controlled string | -| xpathFlow.py:14:20:14:29 | lxml.etree.parse.xpath | externally controlled string | -| xpathFlow.py:23:29:23:38 | lxml.etree.XPath | externally controlled string | -| xpathFlow.py:32:29:32:38 | lxml.etree.XPath | externally controlled string | -| xpathFlow.py:41:31:41:40 | lxml.etree.ETXpath | externally controlled string | -| xpathFlow.py:49:29:49:38 | libxml2.parseFile.xpathEval | externally controlled string | -| xpathGood.py:13:20:13:37 | lxml.etree.parse.xpath | externally controlled string | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-643/xpathSinks.ql b/python/ql/test/experimental/query-tests/Security/CWE-643/xpathSinks.ql deleted file mode 100644 index a9e5aaae4275..000000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-643/xpathSinks.ql +++ /dev/null @@ -1,7 +0,0 @@ -import python -import experimental.semmle.python.security.injection.Xpath -import semmle.python.security.strings.Untrusted - -from XpathInjection::XpathInjectionSink sink, TaintKind kind -where sink.sinks(kind) -select sink, kind