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.ratpack.RatpackExec
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.
*/
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.controlflow.Guards
private import codeql.typeflow.TypeFlow
private import codeql.typeflow.UniversalFlow as UniversalFlow
private module Input implements TypeFlowInput<Location> {
private newtype TTypeFlowNode =
/** 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
}
/** 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
TSsa(BaseSsaVariable ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or
TExpr(Expr e) or
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`.
*/
class TypeFlowNode extends TTypeFlowNode {
class FlowNode extends TFlowNode {
/** Gets a textual representation of this element. */
string toString() {
result = this.asField().toString() or
result = this.asSsa().toString() or
@@ -38,6 +41,7 @@ private module Input implements TypeFlowInput<Location> {
result = this.asMethod().toString()
}
/** Gets the source location for this element. */
Location getLocation() {
result = this.asField().getLocation() or
result = this.asSsa().getLocation() or
@@ -45,14 +49,19 @@ private module Input implements TypeFlowInput<Location> {
result = this.asMethod().getLocation()
}
/** Gets the field corresponding to this node, if any. */
Field asField() { this = TField(result) }
/** Gets the SSA variable corresponding to this node, if any. */
BaseSsaVariable asSsa() { this = TSsa(result) }
/** Gets the expression corresponding to this node, if any. */
Expr asExpr() { this = TExpr(result) }
/** Gets the method corresponding to this node, if any. */
Method asMethod() { this = TMethod(result) }
/** Gets the type of this node. */
RefType getType() {
result = this.asField().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) {
result = viableImpl_v1(c)
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`.
*/
predicate step(TypeFlowNode n1, TypeFlowNode n2) {
predicate step(FlowNode n1, FlowNode n2) {
n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr()
or
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`.
*/
predicate isNullValue(TypeFlowNode n) {
predicate isNullValue(FlowNode n) {
n.asExpr() instanceof NullLiteral
or
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
// reflection and are thus not always null.
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) {
exists(ClassInstanceExpr e |

View File

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

View File

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

View File

@@ -1,4 +1,34 @@
#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: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 |
@@ -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: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
| 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:21:49:21:52 | json | provenance | |
| 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 |
| 7 | Summary: java.lang; CharSequence; true; toString; ; ; Argument[this]; ReturnValue; taint; manual |
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:17:45:17:67 | parse(...) | semmle.label | parse(...) |
| Mongo.java:17:56:17:66 | stringQuery : String | semmle.label | stringQuery : String |