Skip to content

Commit e1bed42

Browse files
committed
JS: Add inline expectation test specifically for TaintedUrlSuffix
1 parent cf90c83 commit e1bed42

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
testFailures
2+
failures
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import javascript
2+
import testUtilities.InlineExpectationsTest
3+
import semmle.javascript.security.TaintedUrlSuffix
4+
5+
module TestConfig implements DataFlow::StateConfigSig {
6+
class FlowState = DataFlow::FlowLabel;
7+
8+
predicate isSource(DataFlow::Node node, DataFlow::FlowLabel state) {
9+
node = TaintedUrlSuffix::source() and state = TaintedUrlSuffix::label()
10+
or
11+
node instanceof RemoteFlowSource and
12+
not node = TaintedUrlSuffix::source() and
13+
state.isTaint()
14+
}
15+
16+
predicate isSink(DataFlow::Node node, DataFlow::FlowLabel state) { none() }
17+
18+
predicate isSink(DataFlow::Node node) {
19+
exists(DataFlow::CallNode call |
20+
call.getCalleeName() = "sink" and
21+
node = call.getArgument(0)
22+
)
23+
}
24+
25+
predicate isAdditionalFlowStep(
26+
DataFlow::Node node1, DataFlow::FlowLabel state1, DataFlow::Node node2,
27+
DataFlow::FlowLabel state2
28+
) {
29+
TaintedUrlSuffix::step(node1, node2, state1, state2)
30+
}
31+
32+
predicate isBarrier(DataFlow::Node node, DataFlow::FlowLabel label) {
33+
TaintedUrlSuffix::isBarrier(node, label)
34+
}
35+
}
36+
37+
module TestFlow = TaintTracking::GlobalWithState<TestConfig>;
38+
39+
module InlineTest implements TestSig {
40+
string getARelevantTag() { result = "flow" }
41+
42+
predicate hasActualResult(Location location, string element, string tag, string value) {
43+
tag = "flow" and
44+
exists(TestFlow::PathNode src, TestFlow::PathNode sink | TestFlow::flowPath(src, sink) |
45+
sink.getLocation() = location and
46+
element = "" and
47+
value = sink.getState()
48+
)
49+
}
50+
}
51+
52+
import MakeTest<InlineTest>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import 'dummy';
2+
3+
function t1() {
4+
const href = window.location.href;
5+
6+
sink(href); // $ flow=tainted-url-suffix
7+
8+
sink(href.split('#')[0]); // $ MISSING: flow=tainted-url-suffix SPURIOUS: flow=taint
9+
sink(href.split('#')[1]); // $ flow=taint
10+
sink(href.split('#').pop()); // $ flow=taint
11+
sink(href.split('#')[2]); // $ flow=taint
12+
13+
sink(href.split('?')[0]); // $ MISSING: flow=tainted-url-suffix
14+
sink(href.split('?')[1]); // $ flow=taint
15+
sink(href.split('?').pop()); // $ flow=taint
16+
sink(href.split('?')[2]); // $ flow=taint
17+
18+
sink(href.split(blah())[0]); // $ flow=tainted-url-suffix
19+
sink(href.split(blah())[1]); // $ flow=tainted-url-suffix
20+
sink(href.split(blah()).pop()); // $ flow=tainted-url-suffix
21+
sink(href.split(blah())[2]); // $ flow=tainted-url-suffix
22+
}

0 commit comments

Comments
 (0)