From b8847dbc5d0328de7c7788abac52680ebf2eb8d5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 5 Oct 2023 09:26:42 +0200 Subject: [PATCH] JS: Port Xxe --- .../javascript/security/dataflow/XxeQuery.qll | 18 +++++- javascript/ql/src/Security/CWE-611/Xxe.ql | 6 +- .../query-tests/Security/CWE-611/Xxe.expected | 56 +++++-------------- 3 files changed, 34 insertions(+), 46 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XxeQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XxeQuery.qll index 82d3fb4f6cc..c82289b28bc 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XxeQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XxeQuery.qll @@ -13,7 +13,23 @@ import XxeCustomizations::Xxe /** * A taint-tracking configuration for reasoning about XXE vulnerabilities. */ -class Configuration extends TaintTracking::Configuration { +module XxeConfig 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 reasoning about XXE vulnerabilities. + */ +module XxeFlow = TaintTracking::Global; + +/** + * DEPRECATED. Use the `XxeFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "Xxe" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/javascript/ql/src/Security/CWE-611/Xxe.ql b/javascript/ql/src/Security/CWE-611/Xxe.ql index 6f544f3a2e5..e1e84e36048 100644 --- a/javascript/ql/src/Security/CWE-611/Xxe.ql +++ b/javascript/ql/src/Security/CWE-611/Xxe.ql @@ -14,10 +14,10 @@ import javascript import semmle.javascript.security.dataflow.XxeQuery -import DataFlow::PathGraph +import XxeFlow::PathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from XxeFlow::PathNode source, XxeFlow::PathNode sink +where XxeFlow::flowPath(source, sink) select sink.getNode(), source, sink, "XML parsing depends on a $@ without guarding against external entity expansion.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected index b625cd91449..8302bf16dd0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected +++ b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected @@ -1,49 +1,21 @@ -nodes -| domparser.js:2:7:2:36 | src | -| domparser.js:2:13:2:36 | documen ... .search | -| domparser.js:2:13:2:36 | documen ... .search | -| domparser.js:11:55:11:57 | src | -| domparser.js:11:55:11:57 | src | -| domparser.js:14:57:14:59 | src | -| domparser.js:14:57:14:59 | src | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:11:21:11:41 | req.par ... e-xml") | -| libxml.noent.js:11:21:11:41 | req.par ... e-xml") | -| libxml.noent.js:11:21:11:41 | req.par ... e-xml") | -| libxml.noent.js:14:27:14:47 | req.par ... e-xml") | -| libxml.noent.js:14:27:14:47 | req.par ... e-xml") | -| libxml.noent.js:14:27:14:47 | req.par ... e-xml") | -| libxml.noent.js:16:27:16:35 | req.files | -| libxml.noent.js:16:27:16:35 | req.files | -| libxml.noent.js:16:27:16:44 | req.files.products | -| libxml.noent.js:16:27:16:49 | req.fil ... ts.data | -| libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | -| libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | edges | domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | -| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | -| domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | | domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | | domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | -| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | -| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | -| libxml.noent.js:11:21:11:41 | req.par ... e-xml") | libxml.noent.js:11:21:11:41 | req.par ... e-xml") | -| libxml.noent.js:14:27:14:47 | req.par ... e-xml") | libxml.noent.js:14:27:14:47 | req.par ... e-xml") | -| libxml.noent.js:16:27:16:35 | req.files | libxml.noent.js:16:27:16:44 | req.files.products | -| libxml.noent.js:16:27:16:35 | req.files | libxml.noent.js:16:27:16:44 | req.files.products | -| libxml.noent.js:16:27:16:44 | req.files.products | libxml.noent.js:16:27:16:49 | req.fil ... ts.data | -| libxml.noent.js:16:27:16:49 | req.fil ... ts.data | libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | -| libxml.noent.js:16:27:16:49 | req.fil ... ts.data | libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | -| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | -| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | +| libxml.noent.js:16:27:16:35 | req.files | libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | +nodes +| domparser.js:2:7:2:36 | src | semmle.label | src | +| domparser.js:2:13:2:36 | documen ... .search | semmle.label | documen ... .search | +| domparser.js:11:55:11:57 | src | semmle.label | src | +| domparser.js:14:57:14:59 | src | semmle.label | src | +| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.noent.js:11:21:11:41 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.noent.js:14:27:14:47 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.noent.js:16:27:16:35 | req.files | semmle.label | req.files | +| libxml.noent.js:16:27:16:66 | req.fil ... 'utf8') | semmle.label | req.fil ... 'utf8') | +| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | semmle.label | req.par ... e-xml") | +subpaths #select | domparser.js:11:55:11:57 | src | domparser.js:2:13:2:36 | documen ... .search | domparser.js:11:55:11:57 | src | XML parsing depends on a $@ without guarding against external entity expansion. | domparser.js:2:13:2:36 | documen ... .search | user-provided value | | domparser.js:14:57:14:59 | src | domparser.js:2:13:2:36 | documen ... .search | domparser.js:14:57:14:59 | src | XML parsing depends on a $@ without guarding against external entity expansion. | domparser.js:2:13:2:36 | documen ... .search | user-provided value |