Skip to content

Commit 2112ecc

Browse files
committed
JS: Migrate HardcodedDataInterpretedAsCode
1 parent dc3d7a0 commit 2112ecc

File tree

2 files changed

+50
-15
lines changed

2 files changed

+50
-15
lines changed

javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCodeCustomizations.qll

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,57 @@ import javascript
88
private import semmle.javascript.security.dataflow.CodeInjectionCustomizations
99

1010
module HardcodedDataInterpretedAsCode {
11+
private newtype TFlowState =
12+
TUnmodified() or
13+
TModified()
14+
15+
/** A flow state to associate with a tracked value. */
16+
class FlowState extends TFlowState {
17+
/** Gets a string representation fo this flow state */
18+
string toString() {
19+
this = TUnmodified() and result = "unmodified"
20+
or
21+
this = TModified() and result = "modified"
22+
}
23+
24+
deprecated DataFlow::FlowLabel toFlowLabel() {
25+
this = TUnmodified() and result.isData()
26+
or
27+
this = TModified() and result.isTaint()
28+
}
29+
}
30+
31+
/** Predicates for working with flow states. */
32+
module FlowState {
33+
deprecated FlowState fromFlowLabel(DataFlow::FlowLabel label) { result.toFlowLabel() = label }
34+
35+
/** An unmodified value originating from a string constant. */
36+
FlowState unmodified() { result = TUnmodified() }
37+
38+
/** A value which has undergone some transformation, such as hex decoding. */
39+
FlowState modified() { result = TModified() }
40+
}
41+
1142
/**
1243
* A data flow source for hard-coded data.
1344
*/
1445
abstract class Source extends DataFlow::Node {
15-
/** Gets a flow label for which this is a source. */
16-
DataFlow::FlowLabel getLabel() { result.isData() }
46+
/** Gets a flow state for which this is a source. */
47+
FlowState getAFlowState() { result = FlowState::unmodified() }
48+
49+
/** DEPRECATED. Use `getAFlowState()` instead. */
50+
deprecated DataFlow::FlowLabel getLabel() { result = this.getAFlowState().toFlowLabel() }
1751
}
1852

1953
/**
2054
* A data flow sink for code injection.
2155
*/
2256
abstract class Sink extends DataFlow::Node {
23-
/** Gets a flow label for which this is a sink. */
24-
abstract DataFlow::FlowLabel getLabel();
57+
/** Gets a flow state for which this is a sink. */
58+
FlowState getAFlowState() { result = FlowState::modified() }
59+
60+
/** DEPRECATED. Use `getAFlowState()` instead. */
61+
deprecated DataFlow::FlowLabel getLabel() { result = this.getAFlowState().toFlowLabel() }
2562

2663
/** Gets a description of what kind of sink this is. */
2764
abstract string getKind();
@@ -50,7 +87,7 @@ module HardcodedDataInterpretedAsCode {
5087
* A code injection sink; hard-coded data should not flow here.
5188
*/
5289
private class DefaultCodeInjectionSink extends Sink instanceof CodeInjection::Sink {
53-
override DataFlow::FlowLabel getLabel() { result.isTaint() }
90+
override FlowState getAFlowState() { result = FlowState::modified() }
5491

5592
override string getKind() { result = "Code" }
5693
}
@@ -61,7 +98,7 @@ module HardcodedDataInterpretedAsCode {
6198
private class RequireArgumentSink extends Sink {
6299
RequireArgumentSink() { this = any(Require r).getAnArgument().flow() }
63100

64-
override DataFlow::FlowLabel getLabel() { result.isDataOrTaint() }
101+
override FlowState getAFlowState() { result = [FlowState::modified(), FlowState::unmodified()] }
65102

66103
override string getKind() { result = "An import path" }
67104
}

javascript/ql/lib/semmle/javascript/security/dataflow/HardcodedDataInterpretedAsCodeQuery.qll

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,27 @@
1010

1111
import javascript
1212
import HardcodedDataInterpretedAsCodeCustomizations::HardcodedDataInterpretedAsCode
13+
private import HardcodedDataInterpretedAsCodeCustomizations::HardcodedDataInterpretedAsCode as HardcodedDataInterpretedAsCode
1314

1415
/**
1516
* A taint-tracking configuration for reasoning about hard-coded data
1617
* being interpreted as code
1718
*/
1819
module HardcodedDataInterpretedAsCodeConfig implements DataFlow::StateConfigSig {
19-
class FlowState = DataFlow::FlowLabel;
20+
class FlowState = HardcodedDataInterpretedAsCode::FlowState;
2021

21-
predicate isSource(DataFlow::Node source, DataFlow::FlowLabel lbl) {
22-
source.(Source).getLabel() = lbl
23-
}
22+
predicate isSource(DataFlow::Node source, FlowState lbl) { source.(Source).getAFlowState() = lbl }
2423

25-
predicate isSink(DataFlow::Node nd, DataFlow::FlowLabel lbl) { nd.(Sink).getLabel() = lbl }
24+
predicate isSink(DataFlow::Node nd, FlowState lbl) { nd.(Sink).getAFlowState() = lbl }
2625

2726
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
2827

2928
predicate isAdditionalFlowStep(
30-
DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2,
31-
DataFlow::FlowLabel state2
29+
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
3230
) {
3331
TaintTracking::defaultTaintStep(node1, node2) and
34-
state1.isDataOrTaint() and
35-
state2.isTaint()
32+
state1 = [FlowState::modified(), FlowState::unmodified()] and
33+
state2 = FlowState::modified()
3634
}
3735
}
3836

0 commit comments

Comments
 (0)