mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
Java: Address review comment. Inline dataflow annotation
This commit is contained in:
@@ -1,15 +1,23 @@
|
||||
import java.lang.ScopedValue;
|
||||
|
||||
public class ScopedValueFlowTest {
|
||||
private static final ScopedValue<String> USER_CONTEXT = ScopedValue.newInstance();
|
||||
private static final ScopedValue<String> SESSION_ID = ScopedValue.newInstance();
|
||||
|
||||
public static String source(String label) {
|
||||
return "tainted";
|
||||
}
|
||||
|
||||
public static void sink(String value) {}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String userInput = args[0]; // source
|
||||
String userInput = source("");
|
||||
|
||||
// Test 1: Basic scoped value binding and retrieval
|
||||
ScopedValue.where(USER_CONTEXT, userInput)
|
||||
.run(() -> {
|
||||
String value = USER_CONTEXT.get();
|
||||
sink(value); // should flag: tainted data reaches sink
|
||||
sink(value); // $ hasTaintFlow
|
||||
});
|
||||
|
||||
// Test 2: Multiple scoped value bindings with chaining
|
||||
@@ -18,8 +26,8 @@ public class ScopedValueFlowTest {
|
||||
.run(() -> {
|
||||
String user = USER_CONTEXT.get();
|
||||
String session = SESSION_ID.get();
|
||||
sink(user); // should flag: tainted data reaches sink
|
||||
sink(session); // should NOT flag
|
||||
sink(user); // $ hasTaintFlow
|
||||
sink(session); // safe - should NOT have taint flow
|
||||
});
|
||||
|
||||
ScopedValue.where(USER_CONTEXT, userInput)
|
||||
@@ -28,12 +36,9 @@ public class ScopedValueFlowTest {
|
||||
ScopedValue.where(USER_CONTEXT, "safe-two")
|
||||
.run(() -> {
|
||||
String inner = USER_CONTEXT.get();
|
||||
sink(inner); // False Positive: currently flags (model limitation
|
||||
sink(inner); // $ SPURIOUS: hasTaintFlow
|
||||
});
|
||||
sink(outer); // should flag: tainted data reaches sink
|
||||
sink(outer); // $ hasTaintFlow
|
||||
});
|
||||
}
|
||||
|
||||
public static void sink(String s) {
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,48 @@
|
||||
| ScopedValueFlowTest.java:6:28:6:34 | ...[...] | ScopedValueFlowTest.java:12:22:12:26 | value |
|
||||
| ScopedValueFlowTest.java:6:28:6:34 | ...[...] | ScopedValueFlowTest.java:21:22:21:25 | user |
|
||||
| ScopedValueFlowTest.java:6:28:6:34 | ...[...] | ScopedValueFlowTest.java:31:30:31:34 | inner |
|
||||
| ScopedValueFlowTest.java:6:28:6:34 | ...[...] | ScopedValueFlowTest.java:33:22:33:26 | outer |
|
||||
models
|
||||
| 1 | Summary: java.lang; ScopedValue; false; where; (ScopedValue,Object); ; Argument[1]; Argument[0].SyntheticField[java.lang.ScopedValue.boundValue]; value; manual |
|
||||
| 2 | Summary: java.lang; ScopedValue; true; get; (); ; Argument[this].SyntheticField[java.lang.ScopedValue.boundValue]; ReturnValue; value; manual |
|
||||
edges
|
||||
| ScopedValueFlowTest.java:4:46:4:57 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:19:32:19:43 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | provenance | |
|
||||
| ScopedValueFlowTest.java:4:46:4:57 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:27:31:27:42 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | provenance | |
|
||||
| ScopedValueFlowTest.java:4:46:4:57 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:35:32:35:43 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | provenance | |
|
||||
| ScopedValueFlowTest.java:4:46:4:57 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:38:40:38:51 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | provenance | |
|
||||
| ScopedValueFlowTest.java:14:28:14:37 | source(...) : String | ScopedValueFlowTest.java:17:41:17:49 | userInput : String | provenance | |
|
||||
| ScopedValueFlowTest.java:14:28:14:37 | source(...) : String | ScopedValueFlowTest.java:24:41:24:49 | userInput : String | provenance | |
|
||||
| ScopedValueFlowTest.java:14:28:14:37 | source(...) : String | ScopedValueFlowTest.java:33:41:33:49 | userInput : String | provenance | |
|
||||
| ScopedValueFlowTest.java:17:27:17:38 | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:4:46:4:57 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | provenance | |
|
||||
| ScopedValueFlowTest.java:17:41:17:49 | userInput : String | ScopedValueFlowTest.java:17:27:17:38 | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String | provenance | MaD:1 |
|
||||
| ScopedValueFlowTest.java:19:32:19:43 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:19:32:19:49 | get(...) : String | provenance | MaD:2 |
|
||||
| ScopedValueFlowTest.java:19:32:19:49 | get(...) : String | ScopedValueFlowTest.java:20:22:20:26 | value | provenance | |
|
||||
| ScopedValueFlowTest.java:24:27:24:38 | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:4:46:4:57 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | provenance | |
|
||||
| ScopedValueFlowTest.java:24:41:24:49 | userInput : String | ScopedValueFlowTest.java:24:27:24:38 | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String | provenance | MaD:1 |
|
||||
| ScopedValueFlowTest.java:27:31:27:42 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:27:31:27:48 | get(...) : String | provenance | MaD:2 |
|
||||
| ScopedValueFlowTest.java:27:31:27:48 | get(...) : String | ScopedValueFlowTest.java:29:22:29:25 | user | provenance | |
|
||||
| ScopedValueFlowTest.java:33:27:33:38 | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:4:46:4:57 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | provenance | |
|
||||
| ScopedValueFlowTest.java:33:41:33:49 | userInput : String | ScopedValueFlowTest.java:33:27:33:38 | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String | provenance | MaD:1 |
|
||||
| ScopedValueFlowTest.java:35:32:35:43 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:35:32:35:49 | get(...) : String | provenance | MaD:2 |
|
||||
| ScopedValueFlowTest.java:35:32:35:49 | get(...) : String | ScopedValueFlowTest.java:41:22:41:26 | outer | provenance | |
|
||||
| ScopedValueFlowTest.java:38:40:38:51 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | ScopedValueFlowTest.java:38:40:38:57 | get(...) : String | provenance | MaD:2 |
|
||||
| ScopedValueFlowTest.java:38:40:38:57 | get(...) : String | ScopedValueFlowTest.java:39:30:39:34 | inner | provenance | |
|
||||
nodes
|
||||
| ScopedValueFlowTest.java:4:46:4:57 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | semmle.label | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String |
|
||||
| ScopedValueFlowTest.java:14:28:14:37 | source(...) : String | semmle.label | source(...) : String |
|
||||
| ScopedValueFlowTest.java:17:27:17:38 | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String | semmle.label | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String |
|
||||
| ScopedValueFlowTest.java:17:41:17:49 | userInput : String | semmle.label | userInput : String |
|
||||
| ScopedValueFlowTest.java:19:32:19:43 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | semmle.label | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String |
|
||||
| ScopedValueFlowTest.java:19:32:19:49 | get(...) : String | semmle.label | get(...) : String |
|
||||
| ScopedValueFlowTest.java:20:22:20:26 | value | semmle.label | value |
|
||||
| ScopedValueFlowTest.java:24:27:24:38 | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String | semmle.label | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String |
|
||||
| ScopedValueFlowTest.java:24:41:24:49 | userInput : String | semmle.label | userInput : String |
|
||||
| ScopedValueFlowTest.java:27:31:27:42 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | semmle.label | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String |
|
||||
| ScopedValueFlowTest.java:27:31:27:48 | get(...) : String | semmle.label | get(...) : String |
|
||||
| ScopedValueFlowTest.java:29:22:29:25 | user | semmle.label | user |
|
||||
| ScopedValueFlowTest.java:33:27:33:38 | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String | semmle.label | USER_CONTEXT [post update] : ScopedValue [java.lang.ScopedValue.boundValue] : String |
|
||||
| ScopedValueFlowTest.java:33:41:33:49 | userInput : String | semmle.label | userInput : String |
|
||||
| ScopedValueFlowTest.java:35:32:35:43 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | semmle.label | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String |
|
||||
| ScopedValueFlowTest.java:35:32:35:49 | get(...) : String | semmle.label | get(...) : String |
|
||||
| ScopedValueFlowTest.java:38:40:38:51 | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String | semmle.label | USER_CONTEXT : ScopedValue [java.lang.ScopedValue.boundValue] : String |
|
||||
| ScopedValueFlowTest.java:38:40:38:57 | get(...) : String | semmle.label | get(...) : String |
|
||||
| ScopedValueFlowTest.java:39:30:39:34 | inner | semmle.label | inner |
|
||||
| ScopedValueFlowTest.java:41:22:41:26 | outer | semmle.label | outer |
|
||||
subpaths
|
||||
testFailures
|
||||
|
||||
@@ -1,24 +1,4 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node n) {
|
||||
exists(ArrayAccess aa |
|
||||
aa.getArray().(VarAccess).getVariable().hasName("args") and
|
||||
n.asExpr() = aa
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node n) {
|
||||
exists(MethodCall ma |
|
||||
ma.getMethod().hasName("sink") and
|
||||
n.asExpr() = ma.getAnArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from DataFlow::Node src, DataFlow::Node sink
|
||||
where Flow::flow(src, sink)
|
||||
select src, sink
|
||||
import utils.test.InlineFlowTest
|
||||
import TaintFlowTest<DefaultFlowConfig>
|
||||
import TaintFlow::PathGraph
|
||||
|
||||
Reference in New Issue
Block a user