Merge pull request #17901 from aschackmull/java/allowlist-sanitizer

Java: Add a default taint sanitizer for contains-checks on lists of constants
This commit is contained in:
Anders Schack-Mulligen
2024-11-27 11:09:05 +01:00
committed by GitHub
15 changed files with 1141 additions and 14 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Calling `coll.contains(x)` is now a taint sanitizer (for any query) for the value `x`, where `coll` is a collection of constants.

View File

@@ -28,6 +28,7 @@ private module Frameworks {
private import semmle.code.java.frameworks.ThreadLocal private import semmle.code.java.frameworks.ThreadLocal
private import semmle.code.java.frameworks.ratpack.RatpackExec private import semmle.code.java.frameworks.ratpack.RatpackExec
private import semmle.code.java.frameworks.stapler.Stapler private import semmle.code.java.frameworks.stapler.Stapler
private import semmle.code.java.security.ListOfConstantsSanitizer
} }
/** /**
@@ -189,3 +190,8 @@ private class NumberTaintPreservingCallable extends TaintPreservingCallable {
* map-key and map-value content, so that e.g. a tainted `Map` is assumed to have tainted keys and values. * map-key and map-value content, so that e.g. a tainted `Map` is assumed to have tainted keys and values.
*/ */
abstract class TaintInheritingContent extends DataFlow::Content { } abstract class TaintInheritingContent extends DataFlow::Content { }
/**
* A sanitizer in all global taint flow configurations but not in local taint.
*/
abstract class DefaultTaintSanitizer extends DataFlow::Node { }

View File

@@ -13,24 +13,27 @@ private import semmle.code.java.dispatch.VirtualDispatch
private import semmle.code.java.dataflow.internal.BaseSSA private import semmle.code.java.dataflow.internal.BaseSSA
private import semmle.code.java.controlflow.Guards private import semmle.code.java.controlflow.Guards
private import codeql.typeflow.TypeFlow private import codeql.typeflow.TypeFlow
private import codeql.typeflow.UniversalFlow as UniversalFlow
private module Input implements TypeFlowInput<Location> { /** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */
private newtype TTypeFlowNode = private RefType boxIfNeeded(J::Type t) {
t.(PrimitiveType).getBoxedType() = result or
result = t
}
/** Provides the input types and predicates for instantiation of `UniversalFlow`. */
module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
private newtype TFlowNode =
TField(Field f) { not f.getType() instanceof PrimitiveType } or TField(Field f) { not f.getType() instanceof PrimitiveType } or
TSsa(BaseSsaVariable ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or TSsa(BaseSsaVariable ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or
TExpr(Expr e) or TExpr(Expr e) or
TMethod(Method m) { not m.getReturnType() instanceof PrimitiveType } TMethod(Method m) { not m.getReturnType() instanceof PrimitiveType }
/** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */
private RefType boxIfNeeded(J::Type t) {
t.(PrimitiveType).getBoxedType() = result or
result = t
}
/** /**
* A `Field`, `BaseSsaVariable`, `Expr`, or `Method`. * A `Field`, `BaseSsaVariable`, `Expr`, or `Method`.
*/ */
class TypeFlowNode extends TTypeFlowNode { class FlowNode extends TFlowNode {
/** Gets a textual representation of this element. */
string toString() { string toString() {
result = this.asField().toString() or result = this.asField().toString() or
result = this.asSsa().toString() or result = this.asSsa().toString() or
@@ -38,6 +41,7 @@ private module Input implements TypeFlowInput<Location> {
result = this.asMethod().toString() result = this.asMethod().toString()
} }
/** Gets the source location for this element. */
Location getLocation() { Location getLocation() {
result = this.asField().getLocation() or result = this.asField().getLocation() or
result = this.asSsa().getLocation() or result = this.asSsa().getLocation() or
@@ -45,14 +49,19 @@ private module Input implements TypeFlowInput<Location> {
result = this.asMethod().getLocation() result = this.asMethod().getLocation()
} }
/** Gets the field corresponding to this node, if any. */
Field asField() { this = TField(result) } Field asField() { this = TField(result) }
/** Gets the SSA variable corresponding to this node, if any. */
BaseSsaVariable asSsa() { this = TSsa(result) } BaseSsaVariable asSsa() { this = TSsa(result) }
/** Gets the expression corresponding to this node, if any. */
Expr asExpr() { this = TExpr(result) } Expr asExpr() { this = TExpr(result) }
/** Gets the method corresponding to this node, if any. */
Method asMethod() { this = TMethod(result) } Method asMethod() { this = TMethod(result) }
/** Gets the type of this node. */
RefType getType() { RefType getType() {
result = this.asField().getType() or result = this.asField().getType() or
result = this.asSsa().getSourceVariable().getType() or result = this.asSsa().getSourceVariable().getType() or
@@ -61,8 +70,6 @@ private module Input implements TypeFlowInput<Location> {
} }
} }
class Type = RefType;
private SrcCallable viableCallable_v1(Call c) { private SrcCallable viableCallable_v1(Call c) {
result = viableImpl_v1(c) result = viableImpl_v1(c)
or or
@@ -88,7 +95,7 @@ private module Input implements TypeFlowInput<Location> {
* *
* For a given `n2`, this predicate must include all possible `n1` that can flow to `n2`. * For a given `n2`, this predicate must include all possible `n1` that can flow to `n2`.
*/ */
predicate step(TypeFlowNode n1, TypeFlowNode n2) { predicate step(FlowNode n1, FlowNode n2) {
n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr() n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr()
or or
exists(Field f, Expr e | exists(Field f, Expr e |
@@ -134,7 +141,7 @@ private module Input implements TypeFlowInput<Location> {
/** /**
* Holds if `null` is the only value that flows to `n`. * Holds if `null` is the only value that flows to `n`.
*/ */
predicate isNullValue(TypeFlowNode n) { predicate isNullValue(FlowNode n) {
n.asExpr() instanceof NullLiteral n.asExpr() instanceof NullLiteral
or or
exists(LocalVariableDeclExpr decl | exists(LocalVariableDeclExpr decl |
@@ -144,11 +151,21 @@ private module Input implements TypeFlowInput<Location> {
) )
} }
predicate isExcludedFromNullAnalysis(TypeFlowNode n) { predicate isExcludedFromNullAnalysis(FlowNode n) {
// Fields that are never assigned a non-null value are probably set by // Fields that are never assigned a non-null value are probably set by
// reflection and are thus not always null. // reflection and are thus not always null.
exists(n.asField()) exists(n.asField())
} }
}
private module Input implements TypeFlowInput<Location> {
import FlowStepsInput
class TypeFlowNode = FlowNode;
predicate isExcludedFromNullAnalysis = FlowStepsInput::isExcludedFromNullAnalysis/1;
class Type = RefType;
predicate exactTypeBase(TypeFlowNode n, RefType t) { predicate exactTypeBase(TypeFlowNode n, RefType t) {
exists(ClassInstanceExpr e | exists(ClassInstanceExpr e |

View File

@@ -38,6 +38,7 @@ class BaseSsaSourceVariable extends TBaseSsaSourceVariable {
/** Gets the `Callable` in which this `BaseSsaSourceVariable` is defined. */ /** Gets the `Callable` in which this `BaseSsaSourceVariable` is defined. */
Callable getEnclosingCallable() { this = TLocalVar(result, _) } Callable getEnclosingCallable() { this = TLocalVar(result, _) }
/** Gets a textual representation of this element. */
string toString() { string toString() {
exists(LocalScopeVariable v, Callable c | this = TLocalVar(c, v) | exists(LocalScopeVariable v, Callable c | this = TLocalVar(c, v) |
if c = v.getCallable() if c = v.getCallable()
@@ -46,6 +47,7 @@ class BaseSsaSourceVariable extends TBaseSsaSourceVariable {
) )
} }
/** Gets the source location for this element. */
Location getLocation() { Location getLocation() {
exists(LocalScopeVariable v | this = TLocalVar(_, v) and result = v.getLocation()) exists(LocalScopeVariable v | this = TLocalVar(_, v) and result = v.getLocation())
} }
@@ -482,8 +484,10 @@ class BaseSsaVariable extends TBaseSsaVariable {
this = TSsaEntryDef(_, result) this = TSsaEntryDef(_, result)
} }
/** Gets a textual representation of this element. */
string toString() { none() } string toString() { none() }
/** Gets the source location for this element. */
Location getLocation() { result = this.getCfgNode().getLocation() } Location getLocation() { result = this.getCfgNode().getLocation() }
/** Gets the `BasicBlock` in which this SSA variable is defined. */ /** Gets the `BasicBlock` in which this SSA variable is defined. */

View File

@@ -161,6 +161,7 @@ private module Cached {
*/ */
cached cached
predicate defaultTaintSanitizer(DataFlow::Node node) { predicate defaultTaintSanitizer(DataFlow::Node node) {
node instanceof DefaultTaintSanitizer or
// Ignore paths through test code. // Ignore paths through test code.
node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass or node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass or
node.asExpr() instanceof ValidatedVariableAccess node.asExpr() instanceof ValidatedVariableAccess

View File

@@ -0,0 +1,263 @@
/**
* Provides a default taint sanitizer identifying comparisons against lists of
* compile-time constants.
*/
import java
private import codeql.typeflow.UniversalFlow as UniversalFlow
private import semmle.code.java.Collections
private import semmle.code.java.controlflow.Guards
private import semmle.code.java.dataflow.internal.BaseSSA
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.dataflow.TypeFlow
private import semmle.code.java.dispatch.VirtualDispatch
private class FlowNode = FlowStepsInput::FlowNode;
/**
* Holds if `n2` is an unmodifiable collection constructed from input `n1`,
* which is either another collection or a number of elements.
*/
private predicate unmodifiableCollectionStep(FlowNode n1, FlowNode n2) {
exists(Call c, Callable tgt |
n2.asExpr() = c and
n1.asExpr() = c.getAnArgument() and
c.getCallee().getSourceDeclaration() = tgt
|
tgt.hasQualifiedName("java.util", "Collections",
["unmodifiableCollection", "unmodifiableList", "unmodifiableSet"])
or
tgt.hasQualifiedName("java.util", ["List", "Set"], ["copyOf", "of"])
or
tgt.hasQualifiedName("com.google.common.collect", ["ImmutableList", "ImmutableSet"],
["copyOf", "of"])
)
}
/**
* Holds if `n2` is a collection or array constructed from input `n1`, which is
* either a collection, an array, or a number of elements.
*/
private predicate collectionStep(FlowNode n1, FlowNode n2) {
n2.asExpr().(ArrayInit).getAnInit() = n1.asExpr()
or
n2.asExpr().(ArrayCreationExpr).getInit() = n1.asExpr()
or
unmodifiableCollectionStep(n1, n2)
or
exists(Call c, Callable tgt |
n2.asExpr() = c and
n1.asExpr() = c.getAnArgument() and
c.getCallee().getSourceDeclaration() = tgt
|
tgt.hasQualifiedName("java.util", "Arrays", "asList")
or
tgt.isStatic() and
tgt.hasName(["copyOf", "of"]) and
tgt.getDeclaringType().getASourceSupertype+().hasQualifiedName("java.util", "Collection")
or
tgt instanceof Constructor and
tgt.getNumberOfParameters() = 1 and
tgt.getParameterType(0) instanceof CollectionType and
tgt.getDeclaringType() instanceof CollectionType
)
}
private module BaseUniversalFlow = UniversalFlow::Make<Location, FlowStepsInput>;
private module UnmodifiableProp implements BaseUniversalFlow::NullaryPropertySig {
predicate hasPropertyBase(FlowNode n) { unmodifiableCollectionStep(_, n) }
}
/** Holds if the given node is an unmodifiable collection. */
private predicate unmodifiableCollection =
BaseUniversalFlow::FlowNullary<UnmodifiableProp>::hasProperty/1;
/**
* Holds if `v` is a collection or array with an access, `coll`, at which the
* element `e` gets added.
*/
private predicate collectionAddition(Variable v, VarAccess coll, Expr e) {
exists(MethodCall mc, Method m, int arg |
mc.getMethod().getSourceDeclaration().overridesOrInstantiates*(m) and
mc.getQualifier() = coll and
v.getAnAccess() = coll and
mc.getArgument(arg) = e
|
m.hasQualifiedName("java.util", "Collection", ["add", "addAll"]) and
m.getNumberOfParameters() = 1 and
arg = 0
or
m.hasQualifiedName("java.util", "List", ["add", "addAll"]) and
m.getNumberOfParameters() = 2 and
arg = 1
or
m.hasQualifiedName("java.util", "SequencedCollection", ["addFirst", "addLast"]) and
m.getNumberOfParameters() = 1 and
arg = 0
)
or
v.getAnAccess() = coll and
exists(Assignment assign | assign.getSource() = e |
coll = assign.getDest().(ArrayAccess).getArray()
)
}
/**
* Holds if `n` represents a definition of `v` and `v` is a collection or
* array that has additions occurring as side-effects after its definition.
*/
private predicate nodeWithAddition(FlowNode n, Variable v) {
collectionAddition(v, _, _) and
(
n.asField() = v
or
n.asSsa().getSourceVariable().getVariable() = v and
(n.asSsa() instanceof BaseSsaUpdate or n.asSsa().(BaseSsaImplicitInit).isParameterDefinition(_))
)
}
/** Holds if `c` does not add elements to the given collection. */
private predicate safeCallable(Callable c) {
c instanceof CollectionQueryMethod
or
c instanceof CollectionMethod and
c.hasName(["clear", "remove", "removeAll", "stream", "iterator", "toArray"])
or
c.hasQualifiedName("org.apache.commons.lang3", "StringUtils", "join")
}
/**
* Holds if `n` might be mutated in ways that adds elements that are not
* tracked by the `collectionAddition` predicate.
*/
private predicate collectionWithPossibleMutation(FlowNode n) {
not unmodifiableCollection(n) and
(
exists(Expr e |
n.asExpr() = e and
(e.getType() instanceof CollectionType or e.getType() instanceof Array) and
not collectionAddition(_, e, _) and
not collectionStep(n, _)
|
exists(ArrayAccess aa | e = aa.getArray())
or
exists(Call c, Callable tgt | c.getAnArgument() = e or c.getQualifier() = e |
tgt = c.getCallee().getSourceDeclaration() and
not safeCallable(tgt)
)
)
or
exists(FlowNode mid |
FlowStepsInput::step(n, mid) and
collectionWithPossibleMutation(mid)
)
)
}
/**
* A collection constructor that constructs an empty mutable collection.
*/
private class EmptyCollectionConstructor extends Constructor {
EmptyCollectionConstructor() {
this.getDeclaringType() instanceof CollectionType and
forall(Type t | t = this.getAParamType() | t instanceof PrimitiveType)
}
}
private module CollectionFlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
import FlowStepsInput
/**
* Holds if `n2` is a collection/array/constant whose value(s) are
* determined completely from the range of `n1` nodes.
*/
predicate step(FlowNode n1, FlowNode n2) {
// Exclude the regular input constraints for those nodes that are covered
// completely by `collectionStep`.
FlowStepsInput::step(n1, n2) and
not collectionStep(_, n2)
or
// For collections with side-effects in the form of additions, we add the
// sources of those additions as additional input that need to originate
// from constants.
exists(Variable v |
nodeWithAddition(n2, v) and
collectionAddition(v, _, n1.asExpr())
)
or
// Include various forms of collection transformation.
collectionStep(n1, n2)
}
predicate isExcludedFromNullAnalysis = FlowStepsInput::isExcludedFromNullAnalysis/1;
}
private module CollectionUniversalFlow = UniversalFlow::Make<Location, CollectionFlowStepsInput>;
private module ConstantCollectionProp implements CollectionUniversalFlow::NullaryPropertySig {
/**
* Holds if `n` forms the base case for finding collections of constants.
* These are individual constants and empty collections.
*/
predicate hasPropertyBase(FlowNode n) {
n.asExpr().isCompileTimeConstant() or
n.asExpr().(ConstructorCall).getConstructor() instanceof EmptyCollectionConstructor
}
predicate barrier = collectionWithPossibleMutation/1;
}
/**
* Holds if the given node is either a constant or a collection/array of
* constants.
*/
private predicate constantCollection =
CollectionUniversalFlow::FlowNullary<ConstantCollectionProp>::hasProperty/1;
/** Gets the result of a case normalization call of `arg`. */
private MethodCall normalizeCaseCall(Expr arg) {
exists(Method changecase | result.getMethod() = changecase |
changecase.hasName(["toUpperCase", "toLowerCase"]) and
changecase.getDeclaringType() instanceof TypeString and
arg = result.getQualifier()
or
changecase
.hasQualifiedName(["org.apache.commons.lang", "org.apache.commons.lang3"], "StringUtils",
["lowerCase", "upperCase"]) and
arg = result.getArgument(0)
or
changecase
.hasQualifiedName("org.apache.hadoop.util", "StringUtils", ["toLowerCase", "toUpperCase"]) and
arg = result.getArgument(0)
)
}
/**
* Holds if the guard `g` ensures that the expression `e` is one of a set of
* known constants upon evaluating to `branch`.
*/
private predicate constantCollectionContainsCheck(Guard g, Expr e, boolean branch) {
exists(MethodCall mc, Method m, FlowNode n, Expr checked |
g = mc and
mc.getMethod().getSourceDeclaration().overridesOrInstantiates*(m) and
m.hasQualifiedName("java.util", "Collection", "contains") and
n.asExpr() = mc.getQualifier() and
constantCollection(n) and
checked = mc.getAnArgument() and
branch = true
|
checked = e or
checked = normalizeCaseCall(e)
)
}
/**
* A comparison against a list of compile-time constants, sanitizing taint by
* restricting to a set of known values.
*/
private class ListOfConstantsComparisonSanitizerGuard extends TaintTracking::DefaultTaintSanitizer {
ListOfConstantsComparisonSanitizerGuard() {
this = DataFlow::BarrierGuard<constantCollectionContainsCheck/3>::getABarrierNode()
}
}

View File

@@ -0,0 +1,35 @@
import java.util.*;
public class A {
private static final Set<String> SEPARATORS =
Collections.unmodifiableSet(
new HashSet<>(Arrays.asList("\t", "\n", ";")));
public static void sink(String s) { }
private void checkSeparator(String separator) {
if (SEPARATORS.contains(separator)) {
sink(separator);
}
}
public static final String URI1 = "yarn.io/gpu";
public static final String URI2 = "yarn.io/fpga";
public static final Set<String> SCHEMAS = Set.of(URI1, URI2, "s3a", "wasb");
private void checkSchema(String schema) {
if (SCHEMAS.contains(schema)) {
sink(schema);
}
}
private void testAdd(String inp) {
Set<String> s = new HashSet<>();
s.add("AA");
s.add("BB");
if (s.contains(inp.toUpperCase())) {
sink(inp);
}
}
}

View File

@@ -0,0 +1 @@
| Type A uses out-of-scope type variable E. Note the Java extractor is known to sometimes do this; the Kotlin extractor should not. |

View File

@@ -0,0 +1,3 @@
| A.java:12:12:12:20 | separator |
| A.java:23:12:23:17 | schema |
| A.java:32:12:32:14 | inp |

View File

@@ -0,0 +1,5 @@
import java
import semmle.code.java.dataflow.FlowSteps
from DefaultTaintSanitizer e
select e

View File

@@ -0,0 +1,306 @@
// Test cases for CWE-089 (SQL injection and Java Persistence query injection)
// http://cwe.mitre.org/data/definitions/89.html
package test.cwe089.semmle.tests;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
class AllowListSanitizerWithJavaUtilList {
public static Connection connection;
public static final List<String> goodAllowList1 = List.of("allowed1", "allowed2", "allowed3");
public static final List<String> goodAllowList2 = Collections.unmodifiableList(Arrays.asList("allowed1"));
public static final List<String> goodAllowList3;
public static final List<String> goodAllowList4;
public static final List<String> goodAllowList5;
public static final List<String> badAllowList1 = List.of("allowed1", "allowed2", getNonConstantString());
public static final List<String> badAllowList2 = Collections.unmodifiableList(Arrays.asList("allowed1", getNonConstantString()));
public static final List<String> badAllowList3;
public static final List<String> badAllowList4;
public static List<String> badAllowList6 = List.of("allowed1", "allowed2", "allowed3");
public final List<String> goodAllowList7 = List.of("allowed1", "allowed2", "allowed3");
static {
goodAllowList3 = List.of("allowed1", "allowed2", "allowed3");
goodAllowList4 = Collections.unmodifiableList(Arrays.asList("allowed1", "allowed2"));
badAllowList3 = List.of(getNonConstantString(), "allowed2", "allowed3");
badAllowList4 = Collections.unmodifiableList(Arrays.asList("allowed1", getNonConstantString()));
goodAllowList5 = new ArrayList<String>();
goodAllowList5.add("allowed1");
goodAllowList5.add("allowed2");
goodAllowList5.add("allowed3");
}
public static String getNonConstantString() {
return String.valueOf(System.currentTimeMillis());
}
public static void main(String[] args) throws IOException, SQLException {
badAllowList6 = List.of("allowed1", getNonConstantString(), "allowed3");
testStaticFields(args);
testLocal(args);
var x = new AllowListSanitizerWithJavaUtilList();
x.testNonStaticFields(args);
testMultipleSources(args);
testEscape(args);
}
private static void testStaticFields(String[] args) throws IOException, SQLException {
String tainted = args[1];
// GOOD: an allowlist is used with constant strings
if(goodAllowList1.contains(tainted.toLowerCase())){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// GOOD: an allowlist is used with constant strings
if(goodAllowList2.contains(tainted.toUpperCase())){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// GOOD: an allowlist is used with constant strings
if(goodAllowList3.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// GOOD: an allowlist is used with constant strings
if(goodAllowList4.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// BAD: an allowlist is used with constant strings
if(badAllowList1.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// BAD: an allowlist is used with constant strings
if(badAllowList2.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// BAD: an allowlist is used with constant strings
if(badAllowList3.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// BAD: an allowlist is used with constant strings
if(badAllowList4.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// GOOD: an allowlist is used with constant strings
if(goodAllowList5.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// BAD: the allowlist is in a non-final field
if(badAllowList6.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
private void testNonStaticFields(String[] args) throws IOException, SQLException {
String tainted = args[0];
// GOOD: the allowlist is in a non-static field
if(goodAllowList7.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
private static void testLocal(String[] args) throws IOException, SQLException {
String tainted = args[1];
// GOOD: an allowlist is used with constant strings
{
List<String> allowlist = List.of("allowed1", "allowed2", "allowed3");
if(allowlist.contains(tainted.toLowerCase())){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but one of the entries is not a compile-time constant
{
List<String> allowlist = List.of("allowed1", "allowed2", args[2]);
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// GOOD: an allowlist is used with constant strings
{
String[] allowedArray = {"allowed1", "allowed2", "allowed3"};
List<String> allowlist = List.of(allowedArray);
if(allowlist.contains(tainted.toUpperCase())){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but one of the entries is not a compile-time constant
{
String[] allowedArray = {"allowed1", "allowed2", args[2]};
List<String> allowlist = List.of(allowedArray);
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// GOOD: an allowlist is used with constant strings
{
List<String> allowlist = Collections.unmodifiableList(Arrays.asList("allowed1"));
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but one of the entries is not a compile-time constant
{
List<String> allowlist = Collections.unmodifiableList(Arrays.asList("allowed1", "allowed2", args[2]));
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// GOOD: an allowlist is used with constant strings
{
String[] allowedArray = {"allowed1", "allowed2", "allowed3"};
List<String> allowlist = Collections.unmodifiableList(Arrays.asList(allowedArray));
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but one of the entries is not a compile-time constant
{
String[] allowedArray = {"allowed1", "allowed2", args[2]};
List<String> allowlist = Collections.unmodifiableList(Arrays.asList(allowedArray));
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// GOOD: an allowlist is used with constant string
{
List<String> allowlist = new ArrayList<String>();
allowlist.add("allowed1");
allowlist.add("allowed2");
allowlist.add("allowed3");
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but one of the entries is not a compile-time constant
{
List<String> allowlist = new ArrayList<String>();
allowlist.add("allowed1");
allowlist.add(getNonConstantString());
allowlist.add("allowed3");
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but it contains a non-compile-time constant element
{
List<String> allowlist = new ArrayList<String>();
allowlist.add("allowed1");
addNonConstantStringDirectly(allowlist);
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
}
private static void testMultipleSources(String[] args) throws IOException, SQLException {
String tainted = args[1];
boolean b = args[2] == "True";
{
// BAD: an allowlist is used which might contain constant strings
List<String> allowlist = new ArrayList<String>();
allowlist.add("allowed1");
if (b) {
allowlist.add(getNonConstantString());
}
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
{
// BAD: an allowlist is used which might contain constant strings
List<String> allowlist = b ? goodAllowList1 : badAllowList1;
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
{
// BAD: an allowlist is used which might contain constant strings
List<String> allowlist = b ? goodAllowList1 : List.of("allowed1", "allowed2", args[2]);;
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
}
private static void testEscape(String[] args) throws IOException, SQLException {
String tainted = args[1];
boolean b = args[2] == "True";
{
// BAD: an allowlist is used which contains constant strings
List<String> allowlist = new ArrayList<String>();
addNonConstantStringViaLambda(e -> allowlist.add(e));
if(allowlist.contains(tainted)){ // missing result
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
}
private static void addNonConstantStringDirectly(List<String> list) {
list.add(getNonConstantString());
}
private static void addNonConstantStringViaLambda(Consumer<String> adder) {
adder.accept(getNonConstantString());
}
}

View File

@@ -0,0 +1,305 @@
// Test cases for CWE-089 (SQL injection and Java Persistence query injection)
// http://cwe.mitre.org/data/definitions/89.html
package test.cwe089.semmle.tests;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashSet;
import java.util.List;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.function.Consumer;
class AllowListSanitizerWithJavaUtilSet {
public static Connection connection;
public static final Set<String> goodAllowList1 = Set.of("allowed1", "allowed2", "allowed3");
public static final Set<String> goodAllowList2 = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("allowed1","allowed2")));
public static final Set<String> goodAllowList3;
public static final Set<String> goodAllowList4;
public static final Set<String> goodAllowList5;
public static final Set<String> badAllowList1 = Set.of("allowed1", "allowed2", getNonConstantString());
public static final Set<String> badAllowList2 = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("allowed1", getNonConstantString())));
public static final Set<String> badAllowList3;
public static final Set<String> badAllowList4;
public static Set<String> badAllowList6 = Set.of("allowed1", "allowed2", "allowed3");
public final Set<String> goodAllowList7 = Set.of("allowed1", "allowed2", "allowed3");
static {
goodAllowList3 = Set.of("allowed1", "allowed2", "allowed3");
goodAllowList4 = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("allowed1", "allowed2")));
badAllowList3 = Set.of(getNonConstantString(), "allowed2", "allowed3");
badAllowList4 = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("allowed1", getNonConstantString())));
goodAllowList5 = new HashSet<String>();
goodAllowList5.add("allowed1");
goodAllowList5.add("allowed2");
goodAllowList5.add("allowed3");
}
public static String getNonConstantString() {
return String.valueOf(System.currentTimeMillis());
}
public static void main(String[] args) throws IOException, SQLException {
badAllowList6 = Set.of("allowed1", getNonConstantString(), "allowed3");
testStaticFields(args);
testLocal(args);
var x = new AllowListSanitizerWithJavaUtilSet();
x.testNonStaticFields(args);
testMultipleSources(args);
testEscape(args);
}
private static void testStaticFields(String[] args) throws IOException, SQLException {
String tainted = args[1];
// GOOD: an allowlist is used with constant strings
if(goodAllowList1.contains(tainted.toLowerCase())){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// GOOD: an allowlist is used with constant strings
if(goodAllowList2.contains(tainted.toUpperCase())){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// GOOD: an allowlist is used with constant strings
if(goodAllowList3.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// GOOD: an allowlist is used with constant strings
if(goodAllowList4.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// BAD: an allowlist is used with constant strings
if(badAllowList1.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// BAD: an allowlist is used with constant strings
if(badAllowList2.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// BAD: an allowlist is used with constant strings
if(badAllowList3.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// BAD: an allowlist is used with constant strings
if(badAllowList4.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// GOOD: an allowlist is used with constant strings
if(goodAllowList5.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
// BAD: the allowlist is in a non-final field
if(badAllowList6.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
private void testNonStaticFields(String[] args) throws IOException, SQLException {
String tainted = args[1];
// GOOD: the allowlist is in a non-static field
if(goodAllowList7.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
private static void testLocal(String[] args) throws IOException, SQLException {
String tainted = args[1];
// GOOD: an allowlist is used with constant strings
{
Set<String> allowlist = Set.of("allowed1", "allowed2", "allowed3");
if(allowlist.contains(tainted.toLowerCase())){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but one of the entries is not a compile-time constant
{
Set<String> allowlist = Set.of("allowed1", "allowed2", args[2]);
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// GOOD: an allowlist is used with constant strings
{
String[] allowedArray = {"allowed1", "allowed2", "allowed3"};
Set<String> allowlist = Set.of(allowedArray);
if(allowlist.contains(tainted.toUpperCase())){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but one of the entries is not a compile-time constant
{
String[] allowedArray = {"allowed1", "allowed2", args[2]};
Set<String> allowlist = Set.of(allowedArray);
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// GOOD: an allowlist is used with constant strings
{
Set<String> allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("allowed1")));
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but one of the entries is not a compile-time constant
{
Set<String> allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("allowed1", "allowed2", args[2])));
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// GOOD: an allowlist is used with constant strings
{
String[] allowedArray = {"allowed1", "allowed2", "allowed3"};
Set<String> allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowedArray)));
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but one of the entries is not a compile-time constant
{
String[] allowedArray = {"allowed1", "allowed2", args[2]};
Set<String> allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowedArray)));
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// GOOD: an allowlist is used with constant string
{
Set<String> allowlist = new HashSet<String>();
allowlist.add("allowed1");
allowlist.add("allowed2");
allowlist.add("allowed3");
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but one of the entries is not a compile-time constant
{
Set<String> allowlist = new HashSet<String>();
allowlist.add("allowed1");
allowlist.add(getNonConstantString());
allowlist.add("allowed3");
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
// BAD: an allowlist is used but it contains a non-compile-time constant element
{
Set<String> allowlist = new HashSet<String>();
allowlist.add("allowed1");
addNonConstantStringDirectly(allowlist);
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
}
private static void testMultipleSources(String[] args) throws IOException, SQLException {
String tainted = args[1];
boolean b = args[2] == "True";
{
// BAD: an allowlist is used which might contain constant strings
Set<String> allowlist = new HashSet<String>();
allowlist.add("allowed1");
if (b) {
allowlist.add(getNonConstantString());
}
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
{
// BAD: an allowlist is used which might contain constant strings
Set<String> allowlist = b ? goodAllowList1 : badAllowList1;
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
{
// BAD: an allowlist is used which might contain constant strings
Set<String> allowlist = b ? goodAllowList1 : Set.of("allowed1", "allowed2", args[2]);;
if(allowlist.contains(tainted)){
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
}
private static void testEscape(String[] args) throws IOException, SQLException {
String tainted = args[1];
boolean b = args[2] == "True";
{
// BAD: an allowlist is used which contains constant strings
Set<String> allowlist = new HashSet<String>();
addNonConstantStringViaLambda(e -> allowlist.add(e));
if(allowlist.contains(tainted)){ // missing result
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ tainted + "' ORDER BY PRICE";
ResultSet results = connection.createStatement().executeQuery(query);
}
}
}
private static void addNonConstantStringDirectly(Set<String> set) {
set.add(getNonConstantString());
}
private static void addNonConstantStringViaLambda(Consumer<String> adder) {
adder.accept(getNonConstantString());
}
}

View File

@@ -0,0 +1 @@
| Type AllowListSanitizerWithJavaUtilSet uses out-of-scope type variable E. Note the Java extractor is known to sometimes do this; the Kotlin extractor should not. |

View File

@@ -1,3 +1,55 @@
| AllowListSanitizerWithJavaUtilList.java:64:66:64:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:63:8:63:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:70:66:70:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:69:8:69:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:76:66:76:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:75:8:75:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:82:66:82:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:81:8:81:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:87:8:87:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:93:8:93:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:99:8:99:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:105:8:105:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:111:8:111:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:117:8:117:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:127:8:127:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:140:67:140:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:139:9:139:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:148:9:148:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:159:67:159:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:158:9:158:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:168:9:168:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:178:67:178:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:177:9:177:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:186:9:186:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:197:67:197:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:196:9:196:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:206:9:206:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:219:67:219:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:218:9:218:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:230:9:230:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:241:9:241:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:259:9:259:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:268:9:268:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:277:9:277:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:292:9:292:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:63:66:63:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:62:8:62:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:69:66:69:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:68:8:68:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:75:66:75:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:74:8:74:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:81:66:81:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:80:8:80:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:86:8:86:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:92:8:92:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:98:8:98:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:104:8:104:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:110:8:110:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:116:8:116:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:126:8:126:14 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:139:67:139:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:138:9:138:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:147:9:147:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:158:67:158:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:157:9:157:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:167:9:167:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:177:67:177:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:176:9:176:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:185:9:185:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:196:67:196:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:195:9:195:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:205:9:205:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:218:67:218:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:217:9:217:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:229:9:229:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:240:9:240:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:258:9:258:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:267:9:267:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:276:9:276:15 | tainted | this expression |
| AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:291:9:291:15 | tainted | this expression |
| Test.java:36:47:36:52 | query1 | Query built by concatenation with $@, which may be untrusted. | Test.java:35:8:35:15 | category | this expression | | Test.java:36:47:36:52 | query1 | Query built by concatenation with $@, which may be untrusted. | Test.java:35:8:35:15 | category | this expression |
| Test.java:42:57:42:62 | query2 | Query built by concatenation with $@, which may be untrusted. | Test.java:41:51:41:52 | id | this expression | | Test.java:42:57:42:62 | query2 | Query built by concatenation with $@, which may be untrusted. | Test.java:41:51:41:52 | id | this expression |
| Test.java:50:62:50:67 | query3 | Query built by concatenation with $@, which may be untrusted. | Test.java:49:8:49:15 | category | this expression | | Test.java:50:62:50:67 | query3 | Query built by concatenation with $@, which may be untrusted. | Test.java:49:8:49:15 | category | this expression |

View File

@@ -1,4 +1,34 @@
#select #select
| AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
| Mongo.java:17:45:17:67 | parse(...) | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:45:17:67 | parse(...) | This query depends on a $@. | Mongo.java:10:29:10:41 | args | user-provided value | | Mongo.java:17:45:17:67 | parse(...) | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:45:17:67 | parse(...) | This query depends on a $@. | Mongo.java:10:29:10:41 | args | user-provided value |
| Mongo.java:21:49:21:52 | json | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | This query depends on a $@. | Mongo.java:10:29:10:41 | args | user-provided value | | Mongo.java:21:49:21:52 | json | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | This query depends on a $@. | Mongo.java:10:29:10:41 | args | user-provided value |
| Test.java:36:47:36:52 | query1 | Test.java:227:26:227:38 | args : String[] | Test.java:36:47:36:52 | query1 | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value | | Test.java:36:47:36:52 | query1 | Test.java:227:26:227:38 | args : String[] | Test.java:36:47:36:52 | query1 | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
@@ -10,6 +40,52 @@
| Test.java:209:47:209:68 | queryWithUserTableName | Test.java:227:26:227:38 | args : String[] | Test.java:209:47:209:68 | queryWithUserTableName | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value | | Test.java:209:47:209:68 | queryWithUserTableName | Test.java:227:26:227:38 | args : String[] | Test.java:209:47:209:68 | queryWithUserTableName | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
| Test.java:221:81:221:111 | ... + ... | Test.java:227:26:227:38 | args : String[] | Test.java:221:81:221:111 | ... + ... | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value | | Test.java:221:81:221:111 | ... + ... | Test.java:227:26:227:38 | args : String[] | Test.java:221:81:221:111 | ... + ... | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
edges edges
| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | provenance | |
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | provenance | Sink:MaD:4 |
| AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | provenance | Sink:MaD:4 |
| Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:56:17:66 | stringQuery : String | provenance | | | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:56:17:66 | stringQuery : String | provenance | |
| Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | provenance | | | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | provenance | |
| Mongo.java:17:56:17:66 | stringQuery : String | Mongo.java:17:45:17:67 | parse(...) | provenance | Config | | Mongo.java:17:56:17:66 | stringQuery : String | Mongo.java:17:45:17:67 | parse(...) | provenance | Config |
@@ -40,6 +116,54 @@ models
| 6 | Summary: java.lang; AbstractStringBuilder; true; append; ; ; Argument[0]; Argument[this]; taint; manual | | 6 | Summary: java.lang; AbstractStringBuilder; true; append; ; ; Argument[0]; Argument[this]; taint; manual |
| 7 | Summary: java.lang; CharSequence; true; toString; ; ; Argument[this]; ReturnValue; taint; manual | | 7 | Summary: java.lang; CharSequence; true; toString; ; ; Argument[this]; ReturnValue; taint; manual |
nodes nodes
| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | semmle.label | query |
| AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | semmle.label | args : String[] |
| AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | semmle.label | query |
| Mongo.java:10:29:10:41 | args : String[] | semmle.label | args : String[] | | Mongo.java:10:29:10:41 | args : String[] | semmle.label | args : String[] |
| Mongo.java:17:45:17:67 | parse(...) | semmle.label | parse(...) | | Mongo.java:17:45:17:67 | parse(...) | semmle.label | parse(...) |
| Mongo.java:17:56:17:66 | stringQuery : String | semmle.label | stringQuery : String | | Mongo.java:17:56:17:66 | stringQuery : String | semmle.label | stringQuery : String |