diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjectionQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjectionQuery.qll index 08e84e834d0..9016c19bd9e 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjectionQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XpathInjectionQuery.qll @@ -14,7 +14,23 @@ import XpathInjectionCustomizations::XpathInjection /** * A taint-tracking configuration for untrusted user input used in XPath expression. */ -class Configuration extends TaintTracking::Configuration { +module XpathInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * Taint-tracking for untrusted user input used in XPath expression. + */ +module XpathInjectionFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `XpathInjectionFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "XpathInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-643/XpathInjection.ql b/javascript/ql/src/Security/CWE-643/XpathInjection.ql index 8a5bfbd791f..c28441d8e24 100644 --- a/javascript/ql/src/Security/CWE-643/XpathInjection.ql +++ b/javascript/ql/src/Security/CWE-643/XpathInjection.ql @@ -13,9 +13,9 @@ import javascript import semmle.javascript.security.dataflow.XpathInjectionQuery -import DataFlow::PathGraph +import XpathInjectionFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from XpathInjectionFlow::PathNode source, XpathInjectionFlow::PathNode sink +where XpathInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "XPath expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected b/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected index f2e28eb3703..5b216204dbe 100644 --- a/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected @@ -1,50 +1,31 @@ -nodes -| XpathInjectionBad.js:6:7:6:38 | userName | -| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | -| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | -| XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | -| XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | -| XpathInjectionBad.js:9:66:9:73 | userName | -| tst2.js:1:13:1:34 | documen ... on.hash | -| tst2.js:1:13:1:34 | documen ... on.hash | -| tst2.js:1:13:1:47 | documen ... ring(1) | -| tst2.js:2:27:2:31 | query | -| tst2.js:2:27:2:31 | query | -| tst2.js:3:19:3:23 | query | -| tst2.js:3:19:3:23 | query | -| tst.js:6:7:6:37 | tainted | -| tst.js:6:17:6:37 | req.par ... rName") | -| tst.js:6:17:6:37 | req.par ... rName") | -| tst.js:7:15:7:21 | tainted | -| tst.js:7:15:7:21 | tainted | -| tst.js:8:16:8:22 | tainted | -| tst.js:8:16:8:22 | tainted | -| tst.js:9:17:9:23 | tainted | -| tst.js:9:17:9:23 | tainted | -| tst.js:11:8:11:14 | tainted | -| tst.js:11:8:11:14 | tainted | edges | XpathInjectionBad.js:6:7:6:38 | userName | XpathInjectionBad.js:9:66:9:73 | userName | | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:6:7:6:38 | userName | -| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:6:7:6:38 | userName | -| XpathInjectionBad.js:9:66:9:73 | userName | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | | XpathInjectionBad.js:9:66:9:73 | userName | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | | tst2.js:1:13:1:34 | documen ... on.hash | tst2.js:1:13:1:47 | documen ... ring(1) | -| tst2.js:1:13:1:34 | documen ... on.hash | tst2.js:1:13:1:47 | documen ... ring(1) | -| tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:2:27:2:31 | query | | tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:2:27:2:31 | query | | tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:3:19:3:23 | query | -| tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:3:19:3:23 | query | -| tst.js:6:7:6:37 | tainted | tst.js:7:15:7:21 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:7:15:7:21 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:8:16:8:22 | tainted | -| tst.js:6:7:6:37 | tainted | tst.js:8:16:8:22 | tainted | -| tst.js:6:7:6:37 | tainted | tst.js:9:17:9:23 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:9:17:9:23 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:11:8:11:14 | tainted | -| tst.js:6:7:6:37 | tainted | tst.js:11:8:11:14 | tainted | -| tst.js:6:17:6:37 | req.par ... rName") | tst.js:6:7:6:37 | tainted | | tst.js:6:17:6:37 | req.par ... rName") | tst.js:6:7:6:37 | tainted | +nodes +| XpathInjectionBad.js:6:7:6:38 | userName | semmle.label | userName | +| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | semmle.label | req.par ... rName") | +| XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | semmle.label | "//user ... text()" | +| XpathInjectionBad.js:9:66:9:73 | userName | semmle.label | userName | +| tst2.js:1:13:1:34 | documen ... on.hash | semmle.label | documen ... on.hash | +| tst2.js:1:13:1:47 | documen ... ring(1) | semmle.label | documen ... ring(1) | +| tst2.js:2:27:2:31 | query | semmle.label | query | +| tst2.js:3:19:3:23 | query | semmle.label | query | +| tst.js:6:7:6:37 | tainted | semmle.label | tainted | +| tst.js:6:17:6:37 | req.par ... rName") | semmle.label | req.par ... rName") | +| tst.js:7:15:7:21 | tainted | semmle.label | tainted | +| tst.js:8:16:8:22 | tainted | semmle.label | tainted | +| tst.js:9:17:9:23 | tainted | semmle.label | tainted | +| tst.js:11:8:11:14 | tainted | semmle.label | tainted | +subpaths #select | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | XPath expression depends on a $@. | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | user-provided value | | tst2.js:2:27:2:31 | query | tst2.js:1:13:1:34 | documen ... on.hash | tst2.js:2:27:2:31 | query | XPath expression depends on a $@. | tst2.js:1:13:1:34 | documen ... on.hash | user-provided value |