Skip to content

Commit 0159f5b

Browse files
committed
Java: Add failing test for Scoped Values
1 parent b4e6d30 commit 0159f5b

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
public class ScopedValueFlowTest {
2+
private static final ScopedValue<String> USER_CONTEXT = ScopedValue.newInstance();
3+
private static final ScopedValue<String> SESSION_ID = ScopedValue.newInstance();
4+
5+
public static void main(String[] args) {
6+
String userInput = args[0]; // source
7+
8+
// Test 1: Basic scoped value binding and retrieval
9+
ScopedValue.where(USER_CONTEXT, userInput)
10+
.run(() -> {
11+
String value = USER_CONTEXT.get();
12+
sink(value); // should flag: tainted data reaches sink
13+
});
14+
15+
// Test 2: Multiple scoped value bindings with chaining
16+
ScopedValue.where(USER_CONTEXT, userInput)
17+
.where(SESSION_ID, "safe-one")
18+
.run(() -> {
19+
String user = USER_CONTEXT.get();
20+
String session = SESSION_ID.get();
21+
sink(user); // should flag: tainted data reaches sink
22+
sink(session); // should NOT flag
23+
});
24+
25+
ScopedValue.where(USER_CONTEXT, userInput)
26+
.run(() -> {
27+
String outer = USER_CONTEXT.get();
28+
ScopedValue.where(USER_CONTEXT, "safe-two")
29+
.run(() -> {
30+
String inner = USER_CONTEXT.get();
31+
sink(inner); // False Positive: currently flags (model limitation
32+
});
33+
sink(outer); // should flag: tainted data reaches sink
34+
});
35+
}
36+
37+
public static void sink(String s) {
38+
}
39+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//semmle-extractor-options: --javac-args -source 25 -target 25 --enable-preview

java/ql/test/library-tests/dataflow/scoped-values/test.expected

Whitespace-only changes.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import java
2+
import semmle.code.java.dataflow.TaintTracking
3+
4+
module Config implements DataFlow::ConfigSig {
5+
predicate isSource(DataFlow::Node n) {
6+
exists(ArrayAccess aa |
7+
aa.getArray().(VarAccess).getVariable().hasName("args") and
8+
n.asExpr() = aa
9+
)
10+
}
11+
12+
predicate isSink(DataFlow::Node n) {
13+
exists(MethodCall ma |
14+
ma.getMethod().hasName("sink") and
15+
n.asExpr() = ma.getAnArgument()
16+
)
17+
}
18+
}
19+
20+
module Flow = TaintTracking::Global<Config>;
21+
22+
from DataFlow::Node src, DataFlow::Node sink
23+
where Flow::flow(src, sink)
24+
select src, sink

0 commit comments

Comments
 (0)