Skip to content

Commit 8887ca1

Browse files
committed
JS: Port an experimental CodeInjection variant to ConfigSig
1 parent 1832e93 commit 8887ca1

File tree

2 files changed

+55
-61
lines changed

2 files changed

+55
-61
lines changed

javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@
1515
*/
1616

1717
import javascript
18-
import DataFlow
19-
import DataFlow::PathGraph
2018

21-
abstract class Sanitizer extends DataFlow::Node { }
19+
abstract class Barrier extends DataFlow::Node { }
2220

2321
/** A non-first leaf in a string-concatenation. Seen as a sanitizer for dynamic import code injection. */
24-
class NonFirstStringConcatLeaf extends Sanitizer {
22+
class NonFirstStringConcatLeaf extends Barrier {
2523
NonFirstStringConcatLeaf() {
2624
exists(StringOps::ConcatenationRoot root |
2725
this = root.getALeaf() and
@@ -51,39 +49,46 @@ class WorkerThreads extends DataFlow::Node {
5149
}
5250
}
5351

54-
class UrlConstructorLabel extends FlowLabel {
52+
class UrlConstructorLabel extends DataFlow::FlowLabel {
5553
UrlConstructorLabel() { this = "UrlConstructorLabel" }
5654
}
5755

5856
/**
5957
* A taint-tracking configuration for reasoning about code injection vulnerabilities.
6058
*/
61-
class Configuration extends TaintTracking::Configuration {
62-
Configuration() { this = "CodeInjection" }
59+
module CodeInjectionConfig implements DataFlow::StateConfigSig {
60+
class FlowState = DataFlow::FlowLabel;
6361

64-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
62+
predicate isSource(DataFlow::Node source, DataFlow::FlowLabel label) {
63+
source instanceof ActiveThreatModelSource and label.isTaint()
64+
}
6565

66-
override predicate isSink(DataFlow::Node sink) { sink instanceof DynamicImport }
66+
predicate isSink(DataFlow::Node sink) { sink instanceof DynamicImport }
6767

68-
override predicate isSink(DataFlow::Node sink, FlowLabel label) {
68+
predicate isSink(DataFlow::Node sink, DataFlow::FlowLabel label) {
6969
sink instanceof WorkerThreads and label instanceof UrlConstructorLabel
7070
}
7171

72-
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
72+
predicate isBarrier(DataFlow::Node node) { node instanceof Barrier }
7373

74-
override predicate isAdditionalFlowStep(
75-
DataFlow::Node pred, DataFlow::Node succ, FlowLabel predlbl, FlowLabel succlbl
74+
predicate isAdditionalFlowStep(
75+
DataFlow::Node pred, DataFlow::FlowLabel predlbl, DataFlow::Node succ,
76+
DataFlow::FlowLabel succlbl
7677
) {
7778
exists(DataFlow::NewNode newUrl | succ = newUrl |
7879
newUrl = DataFlow::globalVarRef("URL").getAnInstantiation() and
7980
pred = newUrl.getArgument(0)
8081
) and
81-
predlbl instanceof StandardFlowLabel and
82+
predlbl.isDataOrTaint() and
8283
succlbl instanceof UrlConstructorLabel
8384
}
8485
}
8586

86-
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
87-
where cfg.hasFlowPath(source, sink)
87+
module CodeInjectionFlow = TaintTracking::GlobalWithState<CodeInjectionConfig>;
88+
89+
import CodeInjectionFlow::PathGraph
90+
91+
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink
92+
where CodeInjectionFlow::flowPath(source, sink)
8893
select sink.getNode(), source, sink, "This command line depends on a $@.", source.getNode(),
8994
"user-provided value"

javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,38 @@
1-
nodes
2-
| test.js:5:11:5:44 | payload |
3-
| test.js:5:21:5:44 | req.que ... rameter |
4-
| test.js:5:21:5:44 | req.que ... rameter |
5-
| test.js:6:9:6:43 | payloadURL |
6-
| test.js:6:22:6:43 | new URL ... + sth) |
7-
| test.js:6:30:6:36 | payload |
8-
| test.js:6:30:6:42 | payload + sth |
9-
| test.js:7:16:7:25 | payloadURL |
10-
| test.js:7:16:7:25 | payloadURL |
11-
| test.js:9:5:9:39 | payloadURL |
12-
| test.js:9:18:9:39 | new URL ... + sth) |
13-
| test.js:9:26:9:32 | payload |
14-
| test.js:9:26:9:38 | payload + sth |
15-
| test.js:10:16:10:25 | payloadURL |
16-
| test.js:10:16:10:25 | payloadURL |
17-
| test.js:17:11:17:44 | payload |
18-
| test.js:17:21:17:44 | req.que ... rameter |
19-
| test.js:17:21:17:44 | req.que ... rameter |
20-
| test.js:18:18:18:24 | payload |
21-
| test.js:18:18:18:24 | payload |
22-
| test.js:19:18:19:24 | payload |
23-
| test.js:19:18:19:30 | payload + sth |
24-
| test.js:19:18:19:30 | payload + sth |
251
edges
26-
| test.js:5:11:5:44 | payload | test.js:6:30:6:36 | payload |
27-
| test.js:5:11:5:44 | payload | test.js:9:26:9:32 | payload |
28-
| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload |
29-
| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload |
30-
| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL |
31-
| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL |
32-
| test.js:6:22:6:43 | new URL ... + sth) | test.js:6:9:6:43 | payloadURL |
33-
| test.js:6:30:6:36 | payload | test.js:6:30:6:42 | payload + sth |
34-
| test.js:6:30:6:42 | payload + sth | test.js:6:22:6:43 | new URL ... + sth) |
35-
| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL |
36-
| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL |
37-
| test.js:9:18:9:39 | new URL ... + sth) | test.js:9:5:9:39 | payloadURL |
38-
| test.js:9:26:9:32 | payload | test.js:9:26:9:38 | payload + sth |
39-
| test.js:9:26:9:38 | payload + sth | test.js:9:18:9:39 | new URL ... + sth) |
40-
| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload |
41-
| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload |
42-
| test.js:17:11:17:44 | payload | test.js:19:18:19:24 | payload |
43-
| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload |
44-
| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload |
45-
| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth |
46-
| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth |
2+
| test.js:5:11:5:44 | payload | test.js:6:30:6:36 | payload | provenance | |
3+
| test.js:5:11:5:44 | payload | test.js:9:26:9:32 | payload | provenance | |
4+
| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload | provenance | |
5+
| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL | provenance | |
6+
| test.js:6:22:6:43 | new URL ... + sth) | test.js:6:9:6:43 | payloadURL | provenance | |
7+
| test.js:6:30:6:36 | payload | test.js:6:30:6:42 | payload + sth | provenance | |
8+
| test.js:6:30:6:42 | payload + sth | test.js:6:22:6:43 | new URL ... + sth) | provenance | Config |
9+
| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL | provenance | |
10+
| test.js:9:18:9:39 | new URL ... + sth) | test.js:9:5:9:39 | payloadURL | provenance | |
11+
| test.js:9:26:9:32 | payload | test.js:9:26:9:38 | payload + sth | provenance | |
12+
| test.js:9:26:9:38 | payload + sth | test.js:9:18:9:39 | new URL ... + sth) | provenance | Config |
13+
| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload | provenance | |
14+
| test.js:17:11:17:44 | payload | test.js:19:18:19:24 | payload | provenance | |
15+
| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload | provenance | |
16+
| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth | provenance | |
17+
nodes
18+
| test.js:5:11:5:44 | payload | semmle.label | payload |
19+
| test.js:5:21:5:44 | req.que ... rameter | semmle.label | req.que ... rameter |
20+
| test.js:6:9:6:43 | payloadURL | semmle.label | payloadURL |
21+
| test.js:6:22:6:43 | new URL ... + sth) | semmle.label | new URL ... + sth) |
22+
| test.js:6:30:6:36 | payload | semmle.label | payload |
23+
| test.js:6:30:6:42 | payload + sth | semmle.label | payload + sth |
24+
| test.js:7:16:7:25 | payloadURL | semmle.label | payloadURL |
25+
| test.js:9:5:9:39 | payloadURL | semmle.label | payloadURL |
26+
| test.js:9:18:9:39 | new URL ... + sth) | semmle.label | new URL ... + sth) |
27+
| test.js:9:26:9:32 | payload | semmle.label | payload |
28+
| test.js:9:26:9:38 | payload + sth | semmle.label | payload + sth |
29+
| test.js:10:16:10:25 | payloadURL | semmle.label | payloadURL |
30+
| test.js:17:11:17:44 | payload | semmle.label | payload |
31+
| test.js:17:21:17:44 | req.que ... rameter | semmle.label | req.que ... rameter |
32+
| test.js:18:18:18:24 | payload | semmle.label | payload |
33+
| test.js:19:18:19:24 | payload | semmle.label | payload |
34+
| test.js:19:18:19:30 | payload + sth | semmle.label | payload + sth |
35+
subpaths
4736
#select
4837
| test.js:7:16:7:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:7:16:7:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value |
4938
| test.js:10:16:10:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:10:16:10:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value |

0 commit comments

Comments
 (0)