diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCodeQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCodeQuery.qll index 7318681a882..55ecdbffe80 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCodeQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCodeQuery.qll @@ -15,7 +15,37 @@ import HardcodedDataInterpretedAsCodeCustomizations::HardcodedDataInterpretedAsC * A taint-tracking configuration for reasoning about hard-coded data * being interpreted as code */ -class Configuration extends TaintTracking::Configuration { +module HardcodedDataInterpretedAsCodeConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowLabel; + + predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) { + source.(Source).getLabel() = lbl + } + + predicate isSink(DataFlow::Node nd, DataFlow::FlowLabel lbl) { nd.(Sink).getLabel() = lbl } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2, + DataFlow::FlowLabel state2 + ) { + TaintTracking::defaultTaintStep(node1, node2) and + state1.isDataOrTaint() and + state2.isTaint() + } +} + +/** + * Taint-tracking for reasoning about hard-coded data being interpreted as code + */ +module HardcodedDataInterpretedAsCodeFlow = + DataFlow::GlobalWithState; + +/** + * DEPRECATED. Use the `HardcodedDataInterpretedAsCodeFlow` module instead. + */ +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "HardcodedDataInterpretedAsCode" } override predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) { diff --git a/javascript/ql/src/Security/CWE-506/HardcodedDataInterpretedAsCode.ql b/javascript/ql/src/Security/CWE-506/HardcodedDataInterpretedAsCode.ql index 9fd53ce9916..bc6a5e5466f 100644 --- a/javascript/ql/src/Security/CWE-506/HardcodedDataInterpretedAsCode.ql +++ b/javascript/ql/src/Security/CWE-506/HardcodedDataInterpretedAsCode.ql @@ -14,10 +14,12 @@ import javascript import semmle.javascript.security.dataflow.HardcodedDataInterpretedAsCodeQuery -import DataFlow::PathGraph +import DataFlow::DeduplicatePathGraph -from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink -where cfg.hasFlowPath(source, sink) +from PathNode source, PathNode sink +where + HardcodedDataInterpretedAsCodeFlow::flowPath(source.getAnOriginalPathNode(), + sink.getAnOriginalPathNode()) select sink.getNode(), source, sink, "$@ is interpreted as " + sink.getNode().(Sink).getKind() + ".", source.getNode(), "Hard-coded data" diff --git a/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected b/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected index 76c630812c5..50fb024e033 100644 --- a/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected +++ b/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected @@ -1,45 +1,46 @@ nodes -| event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | -| event-stream.js:9:11:9:37 | e("2e2f ... 17461") | -| event-stream.js:9:11:9:37 | e("2e2f ... 17461") | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | -| tst.js:1:5:1:88 | totallyHarmlessString | -| tst.js:1:29:1:88 | '636f6e ... 6e2729' | -| tst.js:1:29:1:88 | '636f6e ... 6e2729' | -| tst.js:2:6:2:46 | Buffer. ... 'hex') | -| tst.js:2:6:2:57 | Buffer. ... tring() | -| tst.js:2:6:2:57 | Buffer. ... tring() | -| tst.js:2:18:2:38 | totally ... sString | -| tst.js:5:5:5:23 | test | -| tst.js:5:12:5:23 | "0123456789" | -| tst.js:5:12:5:23 | "0123456789" | -| tst.js:7:8:7:11 | test | -| tst.js:7:8:7:15 | test+"n" | -| tst.js:7:8:7:15 | test+"n" | +| event-stream-orig.js:93:16:93:16 | r | semmle.label | r | +| event-stream-orig.js:94:14:94:34 | Buffer. ... "hex") | semmle.label | Buffer. ... "hex") | +| event-stream-orig.js:94:14:94:45 | Buffer. ... tring() | semmle.label | Buffer. ... tring() | +| event-stream-orig.js:94:26:94:26 | r | semmle.label | r | +| event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | semmle.label | e("2e2f ... 17461") | +| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | semmle.label | "2e2f74 ... 617461" | +| event-stream.js:5:12:5:12 | r | semmle.label | r | +| event-stream.js:6:10:6:30 | Buffer. ... "hex") | semmle.label | Buffer. ... "hex") | +| event-stream.js:6:10:6:41 | Buffer. ... tring() | semmle.label | Buffer. ... tring() | +| event-stream.js:6:22:6:22 | r | semmle.label | r | +| event-stream.js:9:11:9:37 | e("2e2f ... 17461") | semmle.label | e("2e2f ... 17461") | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | semmle.label | "2e2f74 ... 617461" | +| tst.js:1:5:1:88 | totallyHarmlessString | semmle.label | totallyHarmlessString | +| tst.js:1:29:1:88 | '636f6e ... 6e2729' | semmle.label | '636f6e ... 6e2729' | +| tst.js:2:6:2:46 | Buffer. ... 'hex') | semmle.label | Buffer. ... 'hex') | +| tst.js:2:6:2:57 | Buffer. ... tring() | semmle.label | Buffer. ... tring() | +| tst.js:2:18:2:38 | totally ... sString | semmle.label | totally ... sString | +| tst.js:5:5:5:23 | test | semmle.label | test | +| tst.js:5:12:5:23 | "0123456789" | semmle.label | "0123456789" | +| tst.js:7:8:7:11 | test | semmle.label | test | +| tst.js:7:8:7:15 | test+"n" | semmle.label | test+"n" | edges +| event-stream-orig.js:93:16:93:16 | r | event-stream-orig.js:94:26:94:26 | r | +| event-stream-orig.js:94:14:94:34 | Buffer. ... "hex") | event-stream-orig.js:94:14:94:45 | Buffer. ... tring() | +| event-stream-orig.js:94:26:94:26 | r | event-stream-orig.js:94:14:94:34 | Buffer. ... "hex") | +| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:93:16:93:16 | r | | event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | -| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | +| event-stream.js:5:12:5:12 | r | event-stream.js:6:22:6:22 | r | +| event-stream.js:6:10:6:30 | Buffer. ... "hex") | event-stream.js:6:10:6:41 | Buffer. ... tring() | +| event-stream.js:6:22:6:22 | r | event-stream.js:6:10:6:30 | Buffer. ... "hex") | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:5:12:5:12 | r | | event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | | tst.js:1:5:1:88 | totallyHarmlessString | tst.js:2:18:2:38 | totally ... sString | | tst.js:1:29:1:88 | '636f6e ... 6e2729' | tst.js:1:5:1:88 | totallyHarmlessString | -| tst.js:1:29:1:88 | '636f6e ... 6e2729' | tst.js:1:5:1:88 | totallyHarmlessString | -| tst.js:2:6:2:46 | Buffer. ... 'hex') | tst.js:2:6:2:57 | Buffer. ... tring() | | tst.js:2:6:2:46 | Buffer. ... 'hex') | tst.js:2:6:2:57 | Buffer. ... tring() | | tst.js:2:18:2:38 | totally ... sString | tst.js:2:6:2:46 | Buffer. ... 'hex') | | tst.js:5:5:5:23 | test | tst.js:7:8:7:11 | test | | tst.js:5:12:5:23 | "0123456789" | tst.js:5:5:5:23 | test | -| tst.js:5:12:5:23 | "0123456789" | tst.js:5:5:5:23 | test | -| tst.js:7:8:7:11 | test | tst.js:7:8:7:15 | test+"n" | | tst.js:7:8:7:11 | test | tst.js:7:8:7:15 | test+"n" | +subpaths +| event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:93:16:93:16 | r | event-stream-orig.js:94:14:94:45 | Buffer. ... tring() | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:5:12:5:12 | r | event-stream.js:6:10:6:41 | Buffer. ... tring() | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | #select | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | event-stream-orig.js:96:15:96:41 | e("2e2f ... 17461") | $@ is interpreted as An import path. | event-stream-orig.js:96:17:96:40 | "2e2f74 ... 617461" | Hard-coded data | | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | $@ is interpreted as An import path. | event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | Hard-coded data |