Skip to content

Commit 83606e7

Browse files
committed
JS: Dont use data label in taint-tracking configs
1 parent 8da0584 commit 83606e7

3 files changed

Lines changed: 28 additions & 11 deletions

File tree

javascript/ql/src/semmle/javascript/dataflow/Configuration.qll

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,12 @@ private predicate exploratoryFlowStep(
666666
*/
667667
private predicate isSource(DataFlow::Node nd, DataFlow::Configuration cfg, FlowLabel lbl) {
668668
(cfg.isSource(nd) or nd.(AdditionalSource).isSourceFor(cfg)) and
669-
lbl = FlowLabel::data()
669+
(
670+
if cfg instanceof TaintTracking::Configuration then
671+
lbl = FlowLabel::taint()
672+
else
673+
lbl = FlowLabel::data()
674+
)
670675
or
671676
nd.(AdditionalSource).isSourceFor(cfg, lbl)
672677
or
@@ -678,7 +683,12 @@ private predicate isSource(DataFlow::Node nd, DataFlow::Configuration cfg, FlowL
678683
*/
679684
private predicate isSink(DataFlow::Node nd, DataFlow::Configuration cfg, FlowLabel lbl) {
680685
(cfg.isSink(nd) or nd.(AdditionalSink).isSinkFor(cfg)) and
681-
lbl = any(StandardFlowLabel f)
686+
(
687+
if cfg instanceof TaintTracking::Configuration then
688+
lbl = FlowLabel::taint()
689+
else
690+
lbl = FlowLabel::data()
691+
)
682692
or
683693
nd.(AdditionalSink).isSinkFor(cfg, lbl)
684694
or

javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,26 @@ module TaintTracking {
8787
*/
8888
predicate isSanitizerGuard(SanitizerGuardNode guard) { none() }
8989

90-
final override predicate isBarrier(DataFlow::Node node) {
91-
super.isBarrier(node) or
92-
isSanitizer(node) or
93-
node instanceof DataFlow::VarAccessBarrier
90+
override predicate isLabeledBarrier(DataFlow::Node node, DataFlow::FlowLabel lbl) {
91+
super.isLabeledBarrier(node, lbl)
92+
or
93+
isSanitizer(node) and lbl.isTaint()
9494
}
9595

96-
final override predicate isBarrierEdge(DataFlow::Node source, DataFlow::Node sink) {
97-
super.isBarrierEdge(source, sink) or
98-
isSanitizerEdge(source, sink)
96+
override predicate isBarrier(DataFlow::Node node) {
97+
super.isBarrier(node) or
98+
99+
// For variable accesses we block both the data and taint label, as a falsy value
100+
// can't be an object, and thus can't have any tainted properties.
101+
node instanceof DataFlow::VarAccessBarrier
99102
}
100103

101104
final override predicate isBarrierEdge(
102105
DataFlow::Node source, DataFlow::Node sink, DataFlow::FlowLabel lbl
103106
) {
104107
super.isBarrierEdge(source, sink, lbl) or
105-
isSanitizerEdge(source, sink, lbl)
108+
isSanitizerEdge(source, sink, lbl) or
109+
isSanitizerEdge(source, sink) and lbl.isTaint()
106110
}
107111

108112
final override predicate isBarrierGuard(DataFlow::BarrierGuardNode guard) {
@@ -157,7 +161,7 @@ module TaintTracking {
157161
* them.
158162
*/
159163
abstract class SanitizerGuardNode extends DataFlow::BarrierGuardNode {
160-
override predicate blocks(boolean outcome, Expr e) { sanitizes(outcome, e) }
164+
override predicate blocks(boolean outcome, Expr e) { none() }
161165

162166
/**
163167
* Holds if this node sanitizes expression `e`, provided it evaluates
@@ -166,6 +170,8 @@ module TaintTracking {
166170
abstract predicate sanitizes(boolean outcome, Expr e);
167171

168172
override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) {
173+
sanitizes(outcome, e) and label.isTaint()
174+
or
169175
sanitizes(outcome, e, label)
170176
}
171177

javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ typeInferenceMismatch
7373
| nested-props.js:43:13:43:20 | source() | nested-props.js:44:10:44:18 | id(obj).x |
7474
| nested-props.js:67:31:67:38 | source() | nested-props.js:68:10:68:10 | x |
7575
| nested-props.js:77:36:77:43 | source() | nested-props.js:78:10:78:10 | x |
76+
| object-bypass-sanitizer.js:13:13:13:20 | source() | object-bypass-sanitizer.js:6:14:6:18 | x.foo |
7677
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:17:14:17:14 | x |
7778
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:20:14:20:14 | y |
7879
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:30:14:30:20 | x.value |

0 commit comments

Comments
 (0)