Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5f42a71

Browse files
committed
JS: Migrate TaintedObject to a CommonFlowState
1 parent 14ca1c1 commit 5f42a71

3 files changed

Lines changed: 57 additions & 29 deletions

File tree

javascript/ql/lib/semmle/javascript/security/CommonFlowState.qll

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
private import javascript
66
private import TaintedUrlSuffixCustomizations
7+
private import TaintedObjectCustomizations
78

89
private newtype TFlowState =
910
TTaint() or
1011
TTaintedUrlSuffix() or
11-
TTaintedPrefix()
12+
TTaintedPrefix() or
13+
TTaintedObject()
1214

1315
/**
1416
* A flow state indicating which part of a value is tainted.
@@ -30,13 +32,21 @@ class FlowState extends TFlowState {
3032
*/
3133
predicate isTaintedPrefix() { this = TTaintedPrefix() }
3234

35+
/**
36+
* Holds if this represents a deeply tainted object, such as a JSON object
37+
* parsed from user-controlled data.
38+
*/
39+
predicate isTaintedObject() { this = TTaintedObject() }
40+
3341
/** Gets a string representation of this flow state. */
3442
string toString() {
3543
this.isTaint() and result = "taint"
3644
or
3745
this.isTaintedUrlSuffix() and result = "tainted-url-suffix"
3846
or
3947
this.isTaintedPrefix() and result = "tainted-prefix"
48+
or
49+
this.isTaintedObject() and result = "tainted-object"
4050
}
4151

4252
/** DEPRECATED. Gets the corresponding flow label. */
@@ -46,6 +56,8 @@ class FlowState extends TFlowState {
4656
this.isTaintedUrlSuffix() and result = TaintedUrlSuffix::label()
4757
or
4858
this.isTaintedPrefix() and result = "PrefixString"
59+
or
60+
this.isTaintedObject() and result = TaintedObject::label()
4961
}
5062
}
5163

@@ -67,6 +79,12 @@ module FlowState {
6779
*/
6880
FlowState taintedPrefix() { result.isTaintedPrefix() }
6981

82+
/**
83+
* Gets the flow state representing a deeply tainted object, such as a JSON object
84+
* parsed from user-controlled data.
85+
*/
86+
FlowState taintedObject() { result.isTaintedObject() }
87+
7088
/** DEPRECATED. Gets the flow state corresponding to `label`. */
7189
deprecated FlowState fromFlowLabel(DataFlow::FlowLabel label) { result.toFlowLabel() = label }
7290
}

javascript/ql/lib/semmle/javascript/security/TaintedObject.qll

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
*
88
* To track deeply tainted objects, a flow-tracking configuration should generally include the following:
99
*
10-
* 1. One or more sinks associated with the label `TaintedObject::label()`.
11-
* 2. The sources from `TaintedObject::isSource`.
12-
* 3. The flow steps from `TaintedObject::step`.
13-
* 4. The sanitizing guards `TaintedObject::SanitizerGuard`.
10+
* 1. One or more sinks associated with the flow state `FlowState::taintedObject()`.
11+
* 2. The sources from `TaintedObject::Source`.
12+
* 3. The flow steps from `TaintedObject::isAdditionalFlowStep`.
13+
* 4. The barriers from `TaintedObject::SanitizerGuard::getABarrierNode(state)`.
1414
*/
1515

1616
import javascript
@@ -22,35 +22,39 @@ module TaintedObject {
2222
import TaintedObjectCustomizations::TaintedObject
2323

2424
// Materialize flow labels
25-
private class ConcreteTaintedObjectLabel extends TaintedObjectLabel {
25+
deprecated private class ConcreteTaintedObjectLabel extends TaintedObjectLabel {
2626
ConcreteTaintedObjectLabel() { this = this }
2727
}
2828

29+
deprecated predicate step(Node src, Node trg, FlowLabel inlbl, FlowLabel outlbl) {
30+
isAdditionalFlowStep(src, FlowState::fromFlowLabel(inlbl), trg, FlowState::fromFlowLabel(outlbl))
31+
}
32+
2933
/**
3034
* Holds for the flows steps that are relevant for tracking user-controlled JSON objects.
3135
*/
32-
predicate step(Node src, Node trg, FlowLabel inlbl, FlowLabel outlbl) {
36+
predicate isAdditionalFlowStep(Node src, FlowState inlbl, Node trg, FlowState outlbl) {
3337
// JSON parsers map tainted inputs to tainted JSON
34-
inlbl.isDataOrTaint() and
35-
outlbl = label() and
38+
inlbl.isTaint() and
39+
outlbl.isTaintedObject() and
3640
exists(JsonParserCall parse |
3741
src = parse.getInput() and
3842
trg = parse.getOutput()
3943
)
4044
or
4145
// Property reads preserve deep object taint.
42-
inlbl = label() and
43-
outlbl = label() and
46+
inlbl.isTaintedObject() and
47+
outlbl.isTaintedObject() and
4448
trg.(PropRead).getBase() = src
4549
or
4650
// Property projection preserves deep object taint
47-
inlbl = label() and
48-
outlbl = label() and
51+
inlbl.isTaintedObject() and
52+
outlbl.isTaintedObject() and
4953
trg.(PropertyProjection).getObject() = src
5054
or
5155
// Extending objects preserves deep object taint
52-
inlbl = label() and
53-
outlbl = label() and
56+
inlbl.isTaintedObject() and
57+
outlbl.isTaintedObject() and
5458
exists(ExtendCall call |
5559
src = call.getAnOperand() and
5660
trg = call
@@ -60,18 +64,22 @@ module TaintedObject {
6064
)
6165
or
6266
// Spreading into an object preserves deep object taint: `p -> { ...p }`
63-
inlbl = label() and
64-
outlbl = label() and
67+
inlbl.isTaintedObject() and
68+
outlbl.isTaintedObject() and
6569
exists(ObjectLiteralNode obj |
6670
src = obj.getASpreadProperty() and
6771
trg = obj
6872
)
6973
}
7074

7175
/**
76+
* DEPRECATED. Use the `Source` class and `FlowState#isTaintedObject()` directly.
77+
*
7278
* Holds if `node` is a source of JSON taint and label is the JSON taint label.
7379
*/
74-
predicate isSource(Node source, FlowLabel label) { source instanceof Source and label = label() }
80+
deprecated predicate isSource(Node source, FlowLabel label) {
81+
source instanceof Source and label = label()
82+
}
7583

7684
/** Request input accesses as a JSON source. */
7785
private class RequestInputAsSource extends Source {
@@ -86,11 +94,11 @@ module TaintedObject {
8694
predicate blocksExpr(boolean outcome, Expr e) { none() }
8795

8896
/** Holds if this node blocks flow of `label` through `e`, provided it evaluates to `outcome`. */
89-
predicate blocksExpr(boolean outcome, Expr e, FlowLabel label) { none() }
97+
predicate blocksExpr(boolean outcome, Expr e, FlowState label) { none() }
9098

9199
/** DEPRECATED. Use `blocksExpr` instead. */
92100
deprecated predicate sanitizes(boolean outcome, Expr e, FlowLabel label) {
93-
this.blocksExpr(outcome, e, label)
101+
this.blocksExpr(outcome, e, FlowState::fromFlowLabel(label))
94102
}
95103

96104
/** DEPRECATED. Use `blocksExpr` instead. */
@@ -111,7 +119,7 @@ module TaintedObject {
111119
/**
112120
* A sanitizer guard that blocks deep object taint.
113121
*/
114-
module SanitizerGuard = DataFlow::MakeLabeledBarrierGuard<SanitizerGuard>;
122+
module SanitizerGuard = DataFlow::MakeStateBarrierGuard<FlowState, SanitizerGuard>;
115123

116124
/**
117125
* A test of form `typeof x === "something"`, preventing `x` from being an object in some cases.
@@ -133,10 +141,10 @@ module TaintedObject {
133141
)
134142
}
135143

136-
override predicate blocksExpr(boolean outcome, Expr e, FlowLabel label) {
144+
override predicate blocksExpr(boolean outcome, Expr e, FlowState state) {
137145
polarity = outcome and
138146
e = operand and
139-
label = label()
147+
state.isTaintedObject()
140148
}
141149
}
142150

@@ -161,8 +169,8 @@ module TaintedObject {
161169
.getACall()
162170
}
163171

164-
override predicate blocksExpr(boolean outcome, Expr e, FlowLabel lbl) {
165-
e = super.getAnArgument().asExpr() and outcome = true and lbl = label()
172+
override predicate blocksExpr(boolean outcome, Expr e, FlowState state) {
173+
e = super.getAnArgument().asExpr() and outcome = true and state.isTaintedObject()
166174
}
167175
}
168176

@@ -175,10 +183,10 @@ module TaintedObject {
175183

176184
JsonSchemaValidationGuard() { this = call.getAValidationResultAccess(polarity) }
177185

178-
override predicate blocksExpr(boolean outcome, Expr e, FlowLabel label) {
186+
override predicate blocksExpr(boolean outcome, Expr e, FlowState state) {
179187
outcome = polarity and
180188
e = call.getInput().asExpr() and
181-
label = label()
189+
state.isTaintedObject()
182190
}
183191
}
184192
}

javascript/ql/lib/semmle/javascript/security/TaintedObjectCustomizations.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import javascript
77

88
/** Provides classes and predicates for reasoning about deeply tainted objects. */
99
module TaintedObject {
10+
import CommonFlowState
11+
1012
/** A flow label representing a deeply tainted object. */
11-
abstract class TaintedObjectLabel extends DataFlow::FlowLabel {
13+
abstract deprecated class TaintedObjectLabel extends DataFlow::FlowLabel {
1214
TaintedObjectLabel() { this = "tainted-object" }
1315
}
1416

@@ -19,7 +21,7 @@ module TaintedObject {
1921
*
2022
* Note that the presence of the this label generally implies the presence of the `taint` label as well.
2123
*/
22-
DataFlow::FlowLabel label() { result instanceof TaintedObjectLabel }
24+
deprecated DataFlow::FlowLabel label() { result instanceof TaintedObjectLabel }
2325

2426
/**
2527
* A source of a user-controlled deep object.

0 commit comments

Comments
 (0)