Merge branch 'main' into atorralba/promote-groovy-injection

This commit is contained in:
Tony Torralba
2021-07-19 12:44:03 +02:00
2470 changed files with 219463 additions and 31307 deletions

View File

@@ -75,13 +75,25 @@ class GenericType extends RefType {
* Gets the number of type parameters of this generic type.
*/
int getNumberOfTypeParameters() { result = strictcount(getATypeParameter()) }
override string getAPrimaryQlClass() { result = "GenericType" }
}
/** A generic type that is a class. */
class GenericClass extends GenericType, Class { }
class GenericClass extends GenericType, Class {
override string getAPrimaryQlClass() {
result = Class.super.getAPrimaryQlClass() or
result = GenericType.super.getAPrimaryQlClass()
}
}
/** A generic type that is an interface. */
class GenericInterface extends GenericType, Interface { }
class GenericInterface extends GenericType, Interface {
override string getAPrimaryQlClass() {
result = Interface.super.getAPrimaryQlClass() or
result = GenericType.super.getAPrimaryQlClass()
}
}
/**
* A common super-class for Java types that may have a type bound.
@@ -115,6 +127,8 @@ abstract class BoundedType extends RefType, @boundedtype {
or
result = getUpperBoundType().(BoundedType).getAnUltimateUpperBoundType()
}
override string getAPrimaryQlClass() { result = "BoundedType" }
}
/**
@@ -354,13 +368,25 @@ class ParameterizedType extends RefType {
/** Holds if this type originates from source code. */
override predicate fromSource() { typeVars(_, _, _, _, this) and RefType.super.fromSource() }
override string getAPrimaryQlClass() { result = "ParameterizedType" }
}
/** A parameterized type that is a class. */
class ParameterizedClass extends Class, ParameterizedType { }
class ParameterizedClass extends Class, ParameterizedType {
override string getAPrimaryQlClass() {
result = Class.super.getAPrimaryQlClass() or
result = ParameterizedType.super.getAPrimaryQlClass()
}
}
/** A parameterized type that is an interface. */
class ParameterizedInterface extends Interface, ParameterizedType { }
class ParameterizedInterface extends Interface, ParameterizedType {
override string getAPrimaryQlClass() {
result = Interface.super.getAPrimaryQlClass() or
result = ParameterizedType.super.getAPrimaryQlClass()
}
}
/**
* The raw version of a generic type is the type that is formed by
@@ -384,13 +410,25 @@ class RawType extends RefType {
/** Holds if this type originates from source code. */
override predicate fromSource() { not any() }
override string getAPrimaryQlClass() { result = "RawType" }
}
/** A raw type that is a class. */
class RawClass extends Class, RawType { }
class RawClass extends Class, RawType {
override string getAPrimaryQlClass() {
result = Class.super.getAPrimaryQlClass() or
result = RawType.super.getAPrimaryQlClass()
}
}
/** A raw type that is an interface. */
class RawInterface extends Interface, RawType { }
class RawInterface extends Interface, RawType {
override string getAPrimaryQlClass() {
result = Interface.super.getAPrimaryQlClass() or
result = RawType.super.getAPrimaryQlClass()
}
}
// -------- Generic callables --------
/**

View File

@@ -584,9 +584,9 @@ class Field extends Member, ExprParent, @field, Variable {
exists(AssignExpr e, InitializerMethod im |
e.getDest() = this.getAnAccess() and
e.getSource() = result and
result.getEnclosingCallable() = im and
pragma[only_bind_out](result).getEnclosingCallable() = im and
// This rules out updates in explicit initializer blocks as they are nested inside the compiler generated initializer blocks.
e.getEnclosingStmt().getParent() = im.getBody()
pragma[only_bind_out](e.getEnclosingStmt().getParent()) = pragma[only_bind_out](im.getBody())
)
}

View File

@@ -175,6 +175,19 @@ class FormattingCall extends Call {
)
}
/** Gets the `i`th argument to be formatted. The index `i` is one-based. */
Expr getArgumentToBeFormatted(int i) {
i >= 1 and
if this.hasExplicitVarargsArray()
then
result =
this.getArgument(1 + this.getFormatStringIndex())
.(ArrayCreationExpr)
.getInit()
.getInit(i - 1)
else result = this.getArgument(this.getFormatStringIndex() + i)
}
/** Holds if the varargs argument is given as an explicit array. */
private predicate hasExplicitVarargsArray() {
this.getNumArgument() = this.getFormatStringIndex() + 2 and
@@ -353,6 +366,11 @@ class FormatString extends string {
* is not referred by any format specifier.
*/
/*abstract*/ int getASkippedFmtSpecIndex() { none() }
/**
* Gets an offset (zero-based) in this format string where argument `argNo` (1-based) will be interpolated, if any.
*/
int getAnArgUsageOffset(int argNo) { none() }
}
private class PrintfFormatString extends FormatString {
@@ -425,6 +443,22 @@ private class PrintfFormatString extends FormatString {
result > count(int i | fmtSpecRefersToSequentialIndex(i)) and
not result = fmtSpecRefersToSpecificIndex(_)
}
private int getFmtSpecRank(int specOffset) {
rank[result](int i | this.fmtSpecIsRef(i)) = specOffset
}
override int getAnArgUsageOffset(int argNo) {
argNo = fmtSpecRefersToSpecificIndex(result)
or
result = rank[argNo](int i | fmtSpecRefersToSequentialIndex(i))
or
fmtSpecRefersToPrevious(result) and
exists(int previousOffset |
getFmtSpecRank(previousOffset) = getFmtSpecRank(result) - 1 and
previousOffset = getAnArgUsageOffset(argNo)
)
}
}
private class LoggerFormatString extends FormatString {
@@ -449,4 +483,6 @@ private class LoggerFormatString extends FormatString {
}
override int getMaxFmtSpecIndex() { result = count(int i | fmtPlaceholder(i)) }
override int getAnArgUsageOffset(int argNo) { result = rank[argNo](int i | fmtPlaceholder(i)) }
}

View File

@@ -77,17 +77,36 @@ private import FlowSummary
*/
private module Frameworks {
private import internal.ContainerFlow
private import semmle.code.java.frameworks.android.XssSinks
private import semmle.code.java.frameworks.ApacheHttp
private import semmle.code.java.frameworks.apache.Collections
private import semmle.code.java.frameworks.apache.Lang
private import semmle.code.java.frameworks.guava.Guava
private import semmle.code.java.frameworks.jackson.JacksonSerializability
private import semmle.code.java.frameworks.JavaxJson
private import semmle.code.java.frameworks.JaxWS
private import semmle.code.java.frameworks.Optional
private import semmle.code.java.frameworks.spring.SpringCache
private import semmle.code.java.frameworks.spring.SpringHttp
private import semmle.code.java.frameworks.spring.SpringUtil
private import semmle.code.java.frameworks.spring.SpringUi
private import semmle.code.java.frameworks.spring.SpringValidation
private import semmle.code.java.frameworks.spring.SpringWebClient
private import semmle.code.java.frameworks.spring.SpringBeans
private import semmle.code.java.frameworks.spring.SpringWebMultipart
private import semmle.code.java.security.ResponseSplitting
private import semmle.code.java.security.InformationLeak
private import semmle.code.java.security.XSS
private import semmle.code.java.security.JexlInjectionSinkModels
private import semmle.code.java.security.LdapInjection
private import semmle.code.java.security.XPath
private import semmle.code.java.security.JexlInjection
private import semmle.code.java.security.GroovyInjection
private import semmle.code.java.frameworks.android.SQLite
private import semmle.code.java.frameworks.Jdbc
private import semmle.code.java.frameworks.SpringJdbc
private import semmle.code.java.frameworks.MyBatis
private import semmle.code.java.frameworks.Hibernate
private import semmle.code.java.frameworks.jOOQ
private import semmle.code.java.frameworks.spring.SpringHttp
}
private predicate sourceModelCsv(string row) {
@@ -209,6 +228,14 @@ private predicate sinkModelCsv(string row) {
// Open URL
"java.net;URL;false;openConnection;;;Argument[-1];open-url",
"java.net;URL;false;openStream;;;Argument[-1];open-url",
"java.net.http;HttpRequest;false;newBuilder;;;Argument[0];open-url",
"java.net.http;HttpRequest$Builder;false;uri;;;Argument[0];open-url",
"java.net;URLClassLoader;false;URLClassLoader;(URL[]);;Argument[0];open-url",
"java.net;URLClassLoader;false;URLClassLoader;(URL[],ClassLoader);;Argument[0];open-url",
"java.net;URLClassLoader;false;URLClassLoader;(URL[],ClassLoader,URLStreamHandlerFactory);;Argument[0];open-url",
"java.net;URLClassLoader;false;URLClassLoader;(String,URL[],ClassLoader);;Argument[1];open-url",
"java.net;URLClassLoader;false;URLClassLoader;(String,URL[],ClassLoader,URLStreamHandlerFactory);;Argument[1];open-url",
"java.net;URLClassLoader;false;newInstance;;;Argument[0];open-url",
// Create file
"java.io;FileOutputStream;false;FileOutputStream;;;Argument[0];create-file",
"java.io;RandomAccessFile;false;RandomAccessFile;;;Argument[0];create-file",
@@ -248,10 +275,12 @@ private predicate summaryModelCsv(string row) {
"javax.xml.transform.stream;StreamSource;false;getInputStream;;;Argument[-1];ReturnValue;taint",
"java.nio;ByteBuffer;false;get;;;Argument[-1];ReturnValue;taint",
"java.net;URI;false;toURL;;;Argument[-1];ReturnValue;taint",
"java.net;URI;false;toString;;;Argument[-1];ReturnValue;taint",
"java.net;URI;false;toAsciiString;;;Argument[-1];ReturnValue;taint",
"java.io;File;false;toURI;;;Argument[-1];ReturnValue;taint",
"java.io;File;false;toPath;;;Argument[-1];ReturnValue;taint",
"java.nio.file;Path;false;toFile;;;Argument[-1];ReturnValue;taint",
"java.io;Reader;true;readLine;;;Argument[-1];ReturnValue;taint",
"java.io;BufferedReader;true;readLine;;;Argument[-1];ReturnValue;taint",
"java.io;Reader;true;read;();;Argument[-1];ReturnValue;taint",
// arg to return
"java.util;Base64$Encoder;false;encode;(byte[]);;Argument[0];ReturnValue;taint",
@@ -262,8 +291,12 @@ private predicate summaryModelCsv(string row) {
"java.util;Base64$Decoder;false;decode;(ByteBuffer);;Argument[0];ReturnValue;taint",
"java.util;Base64$Decoder;false;decode;(String);;Argument[0];ReturnValue;taint",
"java.util;Base64$Decoder;false;wrap;(InputStream);;Argument[0];ReturnValue;taint",
"org.apache.commons.codec;Encoder;true;encode;;;Argument[0];ReturnValue;taint",
"org.apache.commons.codec;Decoder;true;decode;;;Argument[0];ReturnValue;taint",
"org.apache.commons.codec;Encoder;true;encode;(Object);;Argument[0];ReturnValue;taint",
"org.apache.commons.codec;Decoder;true;decode;(Object);;Argument[0];ReturnValue;taint",
"org.apache.commons.codec;BinaryEncoder;true;encode;(byte[]);;Argument[0];ReturnValue;taint",
"org.apache.commons.codec;BinaryDecoder;true;decode;(byte[]);;Argument[0];ReturnValue;taint",
"org.apache.commons.codec;StringEncoder;true;encode;(String);;Argument[0];ReturnValue;taint",
"org.apache.commons.codec;StringDecoder;true;decode;(String);;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;buffer;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;readLines;;;Argument[0];ReturnValue;taint",
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,int);;Argument[0];ReturnValue;taint",
@@ -407,19 +440,25 @@ predicate summaryModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind
) {
exists(string row |
summaryModel(row) and
row.splitAt(";", 0) = namespace and
row.splitAt(";", 1) = type and
row.splitAt(";", 2) = subtypes.toString() and
subtypes = [true, false] and
row.splitAt(";", 3) = name and
row.splitAt(";", 4) = signature and
row.splitAt(";", 5) = ext and
row.splitAt(";", 6) = input and
row.splitAt(";", 7) = output and
row.splitAt(";", 8) = kind
)
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, _)
}
/** Holds if a summary model `row` exists for the given parameters. */
predicate summaryModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string output, string kind, string row
) {
summaryModel(row) and
row.splitAt(";", 0) = namespace and
row.splitAt(";", 1) = type and
row.splitAt(";", 2) = subtypes.toString() and
subtypes = [true, false] and
row.splitAt(";", 3) = name and
row.splitAt(";", 4) = signature and
row.splitAt(";", 5) = ext and
row.splitAt(";", 6) = input and
row.splitAt(";", 7) = output and
row.splitAt(";", 8) = kind
}
private predicate relevantPackage(string package) {
@@ -555,6 +594,7 @@ module CsvValidation {
}
}
pragma[nomagic]
private predicate elementSpec(
string namespace, string type, boolean subtypes, string name, string signature, string ext
) {
@@ -563,14 +603,6 @@ private predicate elementSpec(
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _)
}
bindingset[namespace, type, subtypes]
private RefType interpretType(string namespace, string type, boolean subtypes) {
exists(RefType t |
t.hasQualifiedName(namespace, type) and
if subtypes = true then result.getASourceSupertype*() = t else result = t
)
}
private string paramsStringPart(Callable c, int i) {
i = -1 and result = "("
or
@@ -591,9 +623,13 @@ private Element interpretElement0(
string namespace, string type, boolean subtypes, string name, string signature
) {
elementSpec(namespace, type, subtypes, name, signature, _) and
exists(RefType t | t = interpretType(namespace, type, subtypes) |
exists(RefType t | t.hasQualifiedName(namespace, type) |
exists(Member m |
result = m and
(
result = m
or
subtypes = true and result.(SrcMethod).overridesOrInstantiates+(m)
) and
m.getDeclaringType() = t and
m.hasName(name)
|
@@ -602,7 +638,7 @@ private Element interpretElement0(
paramsString(m) = signature
)
or
result = t and
(if subtypes = true then result.(SrcRefType).getASourceSupertype*() = t else result = t) and
name = "" and
signature = ""
)
@@ -620,6 +656,48 @@ Element interpretElement(
)
}
private predicate parseField(string c, FieldContent f) {
specSplit(_, c, _) and
exists(string fieldRegex, string package, string className, string fieldName |
fieldRegex = "^Field\\[(.*)\\.([^.]+)\\.([^.]+)\\]$" and
package = c.regexpCapture(fieldRegex, 1) and
className = c.regexpCapture(fieldRegex, 2) and
fieldName = c.regexpCapture(fieldRegex, 3) and
f.getField().hasQualifiedName(package, className, fieldName)
)
}
/** A string representing a synthetic instance field. */
class SyntheticField extends string {
SyntheticField() { parseSynthField(_, this) }
/**
* Gets the type of this field. The default type is `Object`, but this can be
* overridden.
*/
Type getType() { result instanceof TypeObject }
}
private predicate parseSynthField(string c, string f) {
specSplit(_, c, _) and
c.regexpCapture("SyntheticField\\[([.a-zA-Z0-9]+)\\]", 1) = f
}
/** Holds if the specification component parses as a `Content`. */
predicate parseContent(string component, Content content) {
parseField(component, content)
or
parseSynthField(component, content.(SyntheticFieldContent).getField())
or
component = "ArrayElement" and content instanceof ArrayContent
or
component = "Element" and content instanceof CollectionContent
or
component = "MapKey" and content instanceof MapKeyContent
or
component = "MapValue" and content instanceof MapValueContent
}
cached
private module Cached {
/**

View File

@@ -5,7 +5,7 @@
import java
private import internal.FlowSummaryImpl as Impl
private import internal.DataFlowDispatch
private import internal.DataFlowPrivate
private import internal.DataFlowUtil
// import all instances of SummarizedCallable below
private module Summaries {

View File

@@ -5,6 +5,7 @@
import java
import SSA
private import semmle.code.java.controlflow.internal.GuardsLogic
private import semmle.code.java.frameworks.apache.Collections
private import RangeUtils
private import IntegerGuards
@@ -144,11 +145,11 @@ predicate nullCheckMethod(Method m, boolean branch, boolean isnull) {
branch = false and
isnull = false
or
(
m.getDeclaringType().hasQualifiedName("org.apache.commons.collections4", "CollectionUtils") or
m.getDeclaringType().hasQualifiedName("org.apache.commons.collections", "CollectionUtils")
) and
m.hasName("isNotEmpty") and
m instanceof MethodApacheCollectionsIsEmpty and
branch = false and
isnull = false
or
m instanceof MethodApacheCollectionsIsNotEmpty and
branch = true and
isnull = false
or

View File

@@ -68,7 +68,7 @@ private import SSA
private import RangeUtils
private import semmle.code.java.dataflow.internal.rangeanalysis.SsaReadPositionCommon
private import semmle.code.java.controlflow.internal.GuardsLogic
private import semmle.code.java.security.Random
private import semmle.code.java.security.RandomDataSource
private import SignAnalysis
private import ModulusAnalysis
private import semmle.code.java.Reflection

View File

@@ -7,11 +7,11 @@ private import semmle.code.java.dataflow.ExternalFlow
private class EntryType extends RefType {
EntryType() {
this.getSourceDeclaration().getASourceSupertype*().hasQualifiedName("java.util", "Map<>$Entry")
this.getSourceDeclaration().getASourceSupertype*().hasQualifiedName("java.util", "Map$Entry")
}
RefType getValueType() {
exists(GenericType t | t.hasQualifiedName("java.util", "Map<>$Entry") |
exists(GenericType t | t.hasQualifiedName("java.util", "Map$Entry") |
indirectlyInstantiates(this, t, 1, result)
)
}
@@ -95,9 +95,10 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"java.util;Map<>$Entry;true;getValue;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map<>$Entry;true;setValue;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map<>$Entry;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
"java.util;Map$Entry;true;getKey;;;MapKey of Argument[-1];ReturnValue;value",
"java.util;Map$Entry;true;getValue;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map$Entry;true;setValue;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map$Entry;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
"java.lang;Iterable;true;iterator;();;Element of Argument[-1];Element of ReturnValue;value",
"java.lang;Iterable;true;spliterator;();;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Iterator;true;next;;;Element of Argument[-1];ReturnValue;value",
@@ -114,9 +115,9 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
"java.util;Map;true;get;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map;true;getOrDefault;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map;true;getOrDefault;;;Argument[1];ReturnValue;value",
"java.util;Map;true;put;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map;true;put;;;Argument[0];MapKey of Argument[-1];value",
"java.util;Map;true;put;;;Argument[1];MapValue of Argument[-1];value",
"java.util;Map;true;put;(Object,Object);;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map;true;put;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
"java.util;Map;true;put;(Object,Object);;Argument[1];MapValue of Argument[-1];value",
"java.util;Map;true;putIfAbsent;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map;true;putIfAbsent;;;Argument[0];MapKey of Argument[-1];value",
"java.util;Map;true;putIfAbsent;;;Argument[1];MapValue of Argument[-1];value",
@@ -193,6 +194,7 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
"java.util.concurrent;ConcurrentHashMap;true;elements;();;MapValue of Argument[-1];Element of ReturnValue;value",
"java.util;Dictionary;true;elements;();;MapValue of Argument[-1];Element of ReturnValue;value",
"java.util;Dictionary;true;get;(Object);;MapValue of Argument[-1];ReturnValue;value",
"java.util;Dictionary;true;keys;();;MapKey of Argument[-1];Element of ReturnValue;value",
"java.util;Dictionary;true;put;(Object,Object);;MapValue of Argument[-1];ReturnValue;value",
"java.util;Dictionary;true;put;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
"java.util;Dictionary;true;put;(Object,Object);;Argument[1];MapValue of Argument[-1];value",

File diff suppressed because it is too large Load Diff

View File

@@ -724,7 +724,6 @@ private module Cached {
Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType
) {
storeStep(node1, c, node2) and
read(_, c, _) and
contentType = getNodeDataFlowType(node1) and
containerType = getNodeDataFlowType(node2)
or
@@ -1118,6 +1117,44 @@ ReturnPosition getReturnPosition(ReturnNodeExt ret) {
result = getReturnPosition0(ret, ret.getKind())
}
/**
* Checks whether `inner` can return to `call` in the call context `innercc`.
* Assumes a context of `inner = viableCallableExt(call)`.
*/
bindingset[innercc, inner, call]
predicate checkCallContextReturn(CallContext innercc, DataFlowCallable inner, DataFlowCall call) {
innercc instanceof CallContextAny
or
exists(DataFlowCallable c0, DataFlowCall call0 |
callEnclosingCallable(call0, inner) and
innercc = TReturn(c0, call0) and
c0 = prunedViableImplInCallContextReverse(call0, call)
)
}
/**
* Checks whether `call` can resolve to `calltarget` in the call context `cc`.
* Assumes a context of `calltarget = viableCallableExt(call)`.
*/
bindingset[cc, call, calltarget]
predicate checkCallContextCall(CallContext cc, DataFlowCall call, DataFlowCallable calltarget) {
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
if reducedViableImplInCallContext(call, _, ctx)
then calltarget = prunedViableImplInCallContext(call, ctx)
else any()
)
or
cc instanceof CallContextSomeCall
or
cc instanceof CallContextAny
or
cc instanceof CallContextReturn
}
/**
* Resolves a return from `callable` in `cc` to `call`. This is equivalent to
* `callable = viableCallableExt(call) and checkCallContextReturn(cc, callable, call)`.
*/
bindingset[cc, callable]
predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall call) {
cc instanceof CallContextAny and callable = viableCallableExt(call)
@@ -1129,6 +1166,10 @@ predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall
)
}
/**
* Resolves a call from `call` in `cc` to `result`. This is equivalent to
* `result = viableCallableExt(call) and checkCallContextCall(cc, call, result)`.
*/
bindingset[call, cc]
DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) {
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |

View File

@@ -168,7 +168,13 @@ module Consistency {
msg = "ArgumentNode is missing PostUpdateNode."
}
query predicate postWithInFlow(PostUpdateNode n, string msg) {
// This predicate helps the compiler forget that in some languages
// it is impossible for a `PostUpdateNode` to be the target of
// `simpleLocalFlowStep`.
private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() }
query predicate postWithInFlow(Node n, string msg) {
isPostUpdateNode(n) and
simpleLocalFlowStep(_, n) and
msg = "PostUpdateNode should not be the target of local flow."
}

View File

@@ -83,56 +83,6 @@ private predicate instanceFieldAssign(Expr src, FieldAccess fa) {
)
}
private newtype TContent =
TFieldContent(InstanceField f) or
TArrayContent() or
TCollectionContent() or
TMapKeyContent() or
TMapValueContent()
/**
* A reference contained in an object. Examples include instance fields, the
* contents of a collection object, or the contents of an array.
*/
class Content extends TContent {
/** Gets a textual representation of this element. */
abstract string toString();
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
}
}
class FieldContent extends Content, TFieldContent {
InstanceField f;
FieldContent() { this = TFieldContent(f) }
InstanceField getField() { result = f }
override string toString() { result = f.toString() }
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
f.getLocation().hasLocationInfo(path, sl, sc, el, ec)
}
}
class ArrayContent extends Content, TArrayContent {
override string toString() { result = "[]" }
}
class CollectionContent extends Content, TCollectionContent {
override string toString() { result = "<element>" }
}
class MapKeyContent extends Content, TMapKeyContent {
override string toString() { result = "<map.key>" }
}
class MapValueContent extends Content, TMapValueContent {
override string toString() { result = "<map.value>" }
}
/**
* Holds if data can flow from `node1` to `node2` via an assignment to `f`.
* Thus, `node2` references an object with a field `f` that contains the

View File

@@ -157,6 +157,96 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true)
}
private newtype TContent =
TFieldContent(InstanceField f) or
TArrayContent() or
TCollectionContent() or
TMapKeyContent() or
TMapValueContent() or
TSyntheticFieldContent(SyntheticField s)
/**
* A description of the way data may be stored inside an object. Examples
* include instance fields, the contents of a collection object, or the contents
* of an array.
*/
class Content extends TContent {
/** Gets the type of the contained data for the purpose of type pruning. */
abstract DataFlowType getType();
/** Gets a textual representation of this element. */
abstract string toString();
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
*/
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
}
}
/** A reference through an instance field. */
class FieldContent extends Content, TFieldContent {
InstanceField f;
FieldContent() { this = TFieldContent(f) }
InstanceField getField() { result = f }
override DataFlowType getType() { result = getErasedRepr(f.getType()) }
override string toString() { result = f.toString() }
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
f.getLocation().hasLocationInfo(path, sl, sc, el, ec)
}
}
/** A reference through an array. */
class ArrayContent extends Content, TArrayContent {
override DataFlowType getType() { result instanceof TypeObject }
override string toString() { result = "[]" }
}
/** A reference through the contents of some collection-like container. */
class CollectionContent extends Content, TCollectionContent {
override DataFlowType getType() { result instanceof TypeObject }
override string toString() { result = "<element>" }
}
/** A reference through a map key. */
class MapKeyContent extends Content, TMapKeyContent {
override DataFlowType getType() { result instanceof TypeObject }
override string toString() { result = "<map.key>" }
}
/** A reference through a map value. */
class MapValueContent extends Content, TMapValueContent {
override DataFlowType getType() { result instanceof TypeObject }
override string toString() { result = "<map.value>" }
}
/** A reference through a synthetic instance field. */
class SyntheticFieldContent extends Content, TSyntheticFieldContent {
SyntheticField s;
SyntheticFieldContent() { this = TSyntheticFieldContent(s) }
SyntheticField getField() { result = s }
override DataFlowType getType() { result = getErasedRepr(s.getType()) }
override string toString() { result = s.toString() }
}
/**
* A guard that validates some expression.
*

View File

@@ -9,7 +9,7 @@
private import FlowSummaryImplSpecific
private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public
private import DataFlowImplCommon as DataFlowImplCommon
private import DataFlowImplCommon
/** Provides classes and predicates for defining flow summaries. */
module Public {
@@ -295,7 +295,7 @@ module Private {
or
exists(int i |
parameterReadState(c, state, i) and
result.(ParameterNode).isParameterOf(c, i)
result.(ParamNode).isParameterOf(c, i)
)
)
}
@@ -375,7 +375,9 @@ module Private {
or
exists(ReturnKind rk |
head = TReturnSummaryComponent(rk) and
result = getCallbackReturnType(getNodeType(summaryNodeInputState(c, s.drop(1))), rk)
result =
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.drop(1))), rk)
)
)
or
@@ -392,7 +394,9 @@ module Private {
)
or
exists(int i | head = TParameterSummaryComponent(i) |
result = getCallbackParameterType(getNodeType(summaryNodeOutputState(c, s.drop(1))), i)
result =
getCallbackParameterType(getNodeType(summaryNodeOutputState(pragma[only_bind_out](c),
s.drop(1))), i)
)
)
)
@@ -417,7 +421,7 @@ module Private {
}
/** Holds if summary node `post` is a post-update node with pre-update node `pre`. */
predicate summaryPostUpdateNode(Node post, ParameterNode pre) {
predicate summaryPostUpdateNode(Node post, ParamNode pre) {
exists(SummarizedCallable c, int i |
isParameterPostUpdate(post, c, i) and
pre.isParameterOf(c, i)
@@ -489,7 +493,7 @@ module Private {
* Holds if values stored inside content `c` are cleared when passed as
* input of type `input` in `call`.
*/
predicate summaryClearsContent(ArgumentNode arg, Content c) {
predicate summaryClearsContent(ArgNode arg, Content c) {
exists(DataFlowCall call, int i |
viableCallable(call).(SummarizedCallable).clearsContent(i, c) and
arg.argumentOf(call, i)
@@ -497,9 +501,7 @@ module Private {
}
pragma[nomagic]
private ParameterNode summaryArgParam(
ArgumentNode arg, DataFlowImplCommon::ReturnKindExt rk, DataFlowImplCommon::OutNodeExt out
) {
private ParamNode summaryArgParam(ArgNode arg, ReturnKindExt rk, OutNodeExt out) {
exists(DataFlowCall call, int pos, SummarizedCallable callable |
arg.argumentOf(call, pos) and
viableCallable(call) = callable and
@@ -515,8 +517,8 @@ module Private {
* NOTE: This step should not be used in global data-flow/taint-tracking, but may
* be useful to include in the exposed local data-flow/taint-tracking relations.
*/
predicate summaryThroughStep(ArgumentNode arg, Node out, boolean preservesValue) {
exists(DataFlowImplCommon::ReturnKindExt rk, DataFlowImplCommon::ReturnNodeExt ret |
predicate summaryThroughStep(ArgNode arg, Node out, boolean preservesValue) {
exists(ReturnKindExt rk, ReturnNodeExt ret |
summaryLocalStep(summaryArgParam(arg, rk, out), ret, preservesValue) and
ret.getKind() = rk
)
@@ -529,8 +531,8 @@ module Private {
* NOTE: This step should not be used in global data-flow/taint-tracking, but may
* be useful to include in the exposed local data-flow/taint-tracking relations.
*/
predicate summaryGetterStep(ArgumentNode arg, Content c, Node out) {
exists(DataFlowImplCommon::ReturnKindExt rk, Node mid, DataFlowImplCommon::ReturnNodeExt ret |
predicate summaryGetterStep(ArgNode arg, Content c, Node out) {
exists(ReturnKindExt rk, Node mid, ReturnNodeExt ret |
summaryReadStep(summaryArgParam(arg, rk, out), c, mid) and
summaryLocalStep(mid, ret, _) and
ret.getKind() = rk
@@ -544,8 +546,8 @@ module Private {
* NOTE: This step should not be used in global data-flow/taint-tracking, but may
* be useful to include in the exposed local data-flow/taint-tracking relations.
*/
predicate summarySetterStep(ArgumentNode arg, Content c, Node out) {
exists(DataFlowImplCommon::ReturnKindExt rk, Node mid, DataFlowImplCommon::ReturnNodeExt ret |
predicate summarySetterStep(ArgNode arg, Content c, Node out) {
exists(ReturnKindExt rk, Node mid, ReturnNodeExt ret |
summaryLocalStep(summaryArgParam(arg, rk, out), mid, _) and
summaryStoreStep(mid, c, ret) and
ret.getKind() = rk
@@ -559,12 +561,9 @@ module Private {
* definition of `clearsContent()`.
*/
predicate summaryStoresIntoArg(Content c, Node arg) {
exists(
DataFlowImplCommon::ParamUpdateReturnKind rk, DataFlowImplCommon::ReturnNodeExt ret,
PostUpdateNode out
|
exists(ParamUpdateReturnKind rk, ReturnNodeExt ret, PostUpdateNode out |
exists(DataFlowCall call, SummarizedCallable callable |
DataFlowImplCommon::getNodeEnclosingCallable(ret) = callable and
getNodeEnclosingCallable(ret) = callable and
viableCallable(call) = callable and
summaryStoreStep(_, c, ret) and
ret.getKind() = pragma[only_bind_into](rk) and
@@ -643,6 +642,13 @@ module Private {
)
}
/**
* Holds if `spec` specifies summary component stack `stack`.
*/
predicate interpretSpec(string spec, SummaryComponentStack stack) {
interpretSpec(spec, 0, stack)
}
private predicate interpretSpec(string spec, int idx, SummaryComponentStack stack) {
exists(string c |
relevantSpec(spec) and
@@ -681,8 +687,8 @@ module Private {
) {
exists(string inSpec, string outSpec, string kind |
summaryElement(this, inSpec, outSpec, kind) and
interpretSpec(inSpec, 0, input) and
interpretSpec(outSpec, 0, output)
interpretSpec(inSpec, input) and
interpretSpec(outSpec, output)
|
kind = "value" and preservesValue = true
or
@@ -736,21 +742,17 @@ module Private {
specSplit(output, c, idx)
|
exists(int pos |
node.asNode()
.(PostUpdateNode)
.getPreUpdateNode()
.(ArgumentNode)
.argumentOf(mid.asCall(), pos)
node.asNode().(PostUpdateNode).getPreUpdateNode().(ArgNode).argumentOf(mid.asCall(), pos)
|
c = "Argument" or parseArg(c, pos)
)
or
exists(int pos | node.asNode().(ParameterNode).isParameterOf(mid.asCallable(), pos) |
exists(int pos | node.asNode().(ParamNode).isParameterOf(mid.asCallable(), pos) |
c = "Parameter" or parseParam(c, pos)
)
or
c = "ReturnValue" and
node.asNode() = getAnOutNode(mid.asCall(), getReturnValueKind())
node.asNode() = getAnOutNodeExt(mid.asCall(), TValueReturn(getReturnValueKind()))
or
interpretOutputSpecific(c, mid, node)
)
@@ -765,15 +767,15 @@ module Private {
interpretInput(input, idx + 1, ref, mid) and
specSplit(input, c, idx)
|
exists(int pos | node.asNode().(ArgumentNode).argumentOf(mid.asCall(), pos) |
exists(int pos | node.asNode().(ArgNode).argumentOf(mid.asCall(), pos) |
c = "Argument" or parseArg(c, pos)
)
or
exists(ReturnNode ret |
exists(ReturnNodeExt ret |
c = "ReturnValue" and
ret = node.asNode() and
ret.getKind() = getReturnValueKind() and
mid.asCallable() = DataFlowImplCommon::getNodeEnclosingCallable(ret)
ret.getKind().(ValueReturnKind).getKind() = getReturnValueKind() and
mid.asCallable() = getNodeEnclosingCallable(ret)
)
or
interpretInputSpecific(c, mid, node)

View File

@@ -23,21 +23,7 @@ Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = getSum
DataFlowCall summaryDataFlowCall(Node receiver) { none() }
/** Gets the type of content `c`. */
DataFlowType getContentType(Content c) {
result = getErasedRepr(c.(FieldContent).getField().getType())
or
c instanceof CollectionContent and
result instanceof TypeObject
or
c instanceof ArrayContent and
result instanceof TypeObject
or
c instanceof MapKeyContent and
result instanceof TypeObject
or
c instanceof MapValueContent and
result instanceof TypeObject
}
DataFlowType getContentType(Content c) { result = c.getType() }
/** Gets the return type of kind `rk` for callable `c`. */
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) {
@@ -73,13 +59,7 @@ predicate summaryElement(DataFlowCallable c, string input, string output, string
/** Gets the summary component for specification component `c`, if any. */
bindingset[c]
SummaryComponent interpretComponentSpecific(string c) {
c = "ArrayElement" and result = SummaryComponent::content(any(ArrayContent c0))
or
c = "Element" and result = SummaryComponent::content(any(CollectionContent c0))
or
c = "MapKey" and result = SummaryComponent::content(any(MapKeyContent c0))
or
c = "MapValue" and result = SummaryComponent::content(any(MapValueContent c0))
exists(Content content | parseContent(c, content) and result = SummaryComponent::content(content))
}
class SourceOrSinkElement = Top;

View File

@@ -61,16 +61,16 @@ private module Cached {
localAdditionalTaintUpdateStep(src.asExpr(),
sink.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr())
or
exists(Content f |
exists(DataFlow::Content f |
readStep(src, f, sink) and
not sink.getTypeBound() instanceof PrimitiveType and
not sink.getTypeBound() instanceof BoxedType and
not sink.getTypeBound() instanceof NumberType
|
f instanceof ArrayContent or
f instanceof CollectionContent or
f instanceof MapKeyContent or
f instanceof MapValueContent
f instanceof DataFlow::ArrayContent or
f instanceof DataFlow::CollectionContent or
f instanceof DataFlow::MapKeyContent or
f instanceof DataFlow::MapValueContent
)
or
FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false)
@@ -100,90 +100,31 @@ private module Cached {
import Cached
private RefType getElementType(RefType container) {
result = container.(Array).getComponentType() or
result = container.(CollectionType).getElementType() or
result = container.(MapType).getValueType()
}
/**
* These configurations add a number of configuration-dependent additional taint
* steps to all taint configurations. For each sink or additional step provided
* by a given configuration the types are inspected to find those implicit
* collection or array read steps that might be required at the sink or step
* input. The corresponding store steps are then added as additional taint steps
* to provide backwards-compatible taint flow to such sinks and steps.
*
* This is a temporary measure until support is added for such sinks that
* require implicit read steps.
* Holds if default `TaintTracking::Configuration`s should allow implicit reads
* of `c` at sinks and inputs to additional taint steps.
*/
private module StoreTaintSteps {
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.dataflow.TaintTracking2
private class StoreTaintConfig extends TaintTracking::Configuration {
StoreTaintConfig() { this instanceof TaintTracking::Configuration or none() }
override predicate isSource(DataFlow::Node n) { none() }
override predicate isSink(DataFlow::Node n) { none() }
private predicate needsTaintStore(RefType container, Type elem, Content f) {
exists(DataFlow::Node arg |
(isSink(arg) or isAdditionalTaintStep(arg, _)) and
(arg.asExpr() instanceof Argument or arg instanceof ArgumentNode) and
arg.getType() = container
or
needsTaintStore(_, container, _)
|
container.(Array).getComponentType() = elem and
f instanceof ArrayContent
or
container.(CollectionType).getElementType() = elem and
f instanceof CollectionContent
or
container.(MapType).getValueType() = elem and
f instanceof MapValueContent
)
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(Content f, Type elem |
storeStep(node1, f, node2) and
needsTaintStore(_, elem, f) and
not exists(Type srctyp | srctyp = node1.getTypeBound() | not compatibleTypes(srctyp, elem))
)
}
}
private class StoreTaintConfig2 extends TaintTracking2::Configuration {
StoreTaintConfig2() { this instanceof TaintTracking2::Configuration or none() }
override predicate isSource(DataFlow::Node n) { none() }
override predicate isSink(DataFlow::Node n) { none() }
private predicate needsTaintStore(RefType container, Type elem, Content f) {
exists(DataFlow::Node arg |
(isSink(arg) or isAdditionalTaintStep(arg, _)) and
(arg.asExpr() instanceof Argument or arg instanceof ArgumentNode) and
arg.getType() = container
or
needsTaintStore(_, container, _)
|
container.(Array).getComponentType() = elem and
f instanceof ArrayContent
or
container.(CollectionType).getElementType() = elem and
f instanceof CollectionContent
or
container.(MapType).getValueType() = elem and
f instanceof MapValueContent
)
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(Content f, Type elem |
storeStep(node1, f, node2) and
needsTaintStore(_, elem, f) and
not exists(Type srctyp | srctyp = node1.getTypeBound() | not compatibleTypes(srctyp, elem))
)
}
}
bindingset[node]
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) {
exists(RefType container |
(node.asExpr() instanceof Argument or node instanceof ArgumentNode) and
getElementType*(node.getType()) = container
|
container instanceof Array and
c instanceof DataFlow::ArrayContent
or
container instanceof CollectionType and
c instanceof DataFlow::CollectionContent
or
container instanceof MapType and
c instanceof DataFlow::MapValueContent
)
}
/**
@@ -268,22 +209,6 @@ private predicate constructorStep(Expr tracked, ConstructorCall sink) {
// a custom InputStream that wraps a tainted data source is tainted
inputStreamWrapper(sink.getConstructor(), argi)
or
// A SpringHttpEntity is a wrapper around a body and some headers
// Track flow through iff body is a String
exists(SpringHttpEntity she |
sink.getConstructor() = she.getAConstructor() and
argi = 0 and
tracked.getType() instanceof TypeString
)
or
// A SpringRequestEntity is a wrapper around a body and some headers
// Track flow through iff body is a String
exists(SpringResponseEntity sre |
sink.getConstructor() = sre.getAConstructor() and
argi = 0 and
tracked.getType() instanceof TypeString
)
or
sink.getConstructor().(TaintPreservingCallable).returnsTaintFrom(argToParam(sink, argi))
)
}
@@ -336,19 +261,6 @@ private predicate taintPreservingQualifierToMethod(Method m) {
m.getDeclaringType().getASubtype*() instanceof SpringUntrustedDataType and
not m.getDeclaringType() instanceof TypeObject
or
m.getDeclaringType() instanceof SpringHttpEntity and
m.getName().regexpMatch("getBody|getHeaders")
or
exists(SpringHttpHeaders headers | m = headers.getAMethod() |
m.getReturnType() instanceof TypeString
or
exists(ParameterizedType stringlist |
m.getReturnType().(RefType).getASupertype*() = stringlist and
stringlist.getSourceDeclaration().hasQualifiedName("java.util", "List") and
stringlist.getTypeArgument(0) instanceof TypeString
)
)
or
m.(TaintPreservingCallable).returnsTaintFrom(-1)
or
exists(JaxRsResourceMethod resourceMethod |

View File

@@ -105,6 +105,11 @@ abstract class Configuration extends DataFlow::Configuration {
defaultAdditionalTaintStep(node1, node2)
}
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) {
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
defaultImplicitTaintRead(node, c)
}
/**
* Holds if taint may flow from `source` to `sink` for this configuration.
*/

View File

@@ -105,6 +105,11 @@ abstract class Configuration extends DataFlow::Configuration {
defaultAdditionalTaintStep(node1, node2)
}
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) {
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
defaultImplicitTaintRead(node, c)
}
/**
* Holds if taint may flow from `source` to `sink` for this configuration.
*/

View File

@@ -92,6 +92,39 @@ private class ApacheHttpXssSink extends SinkModelCsv {
}
}
private class ApacheHttpOpenUrlSink extends SinkModelCsv {
override predicate row(string row) {
row =
[
"org.apache.http;HttpRequest;true;setURI;;;Argument[0];open-url",
"org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(RequestLine);;Argument[0];open-url",
"org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(String,String);;Argument[1];open-url",
"org.apache.http.message;BasicHttpRequest;false;BasicHttpRequest;(String,String,ProtocolVersion);;Argument[1];open-url",
"org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(RequestLine);;Argument[0];open-url",
"org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(String,String);;Argument[1];open-url",
"org.apache.http.message;BasicHttpEntityEnclosingRequest;false;BasicHttpEntityEnclosingRequest;(String,String,ProtocolVersion);;Argument[1];open-url",
"org.apache.http.client.methods;HttpGet;false;HttpGet;;;Argument[0];open-url",
"org.apache.http.client.methods;HttpHead;false;HttpHead;;;Argument[0];open-url",
"org.apache.http.client.methods;HttpPut;false;HttpPut;;;Argument[0];open-url",
"org.apache.http.client.methods;HttpPost;false;HttpPost;;;Argument[0];open-url",
"org.apache.http.client.methods;HttpDelete;false;HttpDelete;;;Argument[0];open-url",
"org.apache.http.client.methods;HttpOptions;false;HttpOptions;;;Argument[0];open-url",
"org.apache.http.client.methods;HttpTrace;false;HttpTrace;;;Argument[0];open-url",
"org.apache.http.client.methods;HttpPatch;false;HttpPatch;;;Argument[0];open-url",
"org.apache.http.client.methods;HttpRequestBase;true;setURI;;;Argument[0];open-url",
"org.apache.http.client.methods;RequestBuilder;false;setUri;;;Argument[0];open-url",
"org.apache.http.client.methods;RequestBuilder;false;get;;;Argument[0];open-url",
"org.apache.http.client.methods;RequestBuilder;false;post;;;Argument[0];open-url",
"org.apache.http.client.methods;RequestBuilder;false;put;;;Argument[0];open-url",
"org.apache.http.client.methods;RequestBuilder;false;options;;;Argument[0];open-url",
"org.apache.http.client.methods;RequestBuilder;false;head;;;Argument[0];open-url",
"org.apache.http.client.methods;RequestBuilder;false;delete;;;Argument[0];open-url",
"org.apache.http.client.methods;RequestBuilder;false;trace;;;Argument[0];open-url",
"org.apache.http.client.methods;RequestBuilder;false;patch;;;Argument[0];open-url"
]
}
}
private class ApacheHttpFlowStep extends SummaryModelCsv {
override predicate row(string row) {
row =
@@ -228,7 +261,10 @@ private class ApacheHttpFlowStep extends SummaryModelCsv {
"org.apache.hc.core5.util;CharArrayBuffer;true;toString;();;Argument[-1];ReturnValue;taint",
"org.apache.hc.core5.util;CharArrayBuffer;true;substring;(int,int);;Argument[-1];ReturnValue;taint",
"org.apache.hc.core5.util;CharArrayBuffer;true;subSequence;(int,int);;Argument[-1];ReturnValue;taint",
"org.apache.hc.core5.util;CharArrayBuffer;true;substringTrimmed;(int,int);;Argument[-1];ReturnValue;taint"
"org.apache.hc.core5.util;CharArrayBuffer;true;substringTrimmed;(int,int);;Argument[-1];ReturnValue;taint",
"org.apache.http.message;BasicRequestLine;false;BasicRequestLine;;;Argument[1];Argument[-1];taint",
"org.apache.http;RequestLine;true;getUri;;;Argument[-1];ReturnValue;taint",
"org.apache.http;RequestLine;true;toString;;;Argument[-1];ReturnValue;taint"
]
}
}

View File

@@ -0,0 +1,20 @@
/**
* Provides classes and predicates for working with the Castor framework.
*/
import java
/**
* The class `org.exolab.castor.xml.Unmarshaller`.
*/
class CastorUnmarshaller extends RefType {
CastorUnmarshaller() { this.hasQualifiedName("org.exolab.castor.xml", "Unmarshaller") }
}
/** A method with the name `unmarshal` declared in `org.exolab.castor.xml.Unmarshaller`. */
class CastorUnmarshalMethod extends Method {
CastorUnmarshalMethod() {
this.getDeclaringType() instanceof CastorUnmarshaller and
this.getName() = "unmarshal"
}
}

View File

@@ -0,0 +1,49 @@
/**
* Provides classes and predicates for working with the HessianBurlap framework.
*/
import java
/**
* The classes `[com.alibaba.]com.caucho.hessian.io.AbstractHessianInput` or `[com.alibaba.]com.caucho.hessian.io.Hessian2StreamingInput`.
*/
class UnsafeHessianInput extends RefType {
UnsafeHessianInput() {
this.hasQualifiedName(["com.caucho.hessian.io", "com.alibaba.com.caucho.hessian.io"],
["AbstractHessianInput", "Hessian2StreamingInput"])
}
}
/**
* A AbstractHessianInput or Hessian2StreamingInput subclass readObject method.
* This is either `AbstractHessianInput.readObject` or `Hessian2StreamingInput.readObject`.
*/
class UnsafeHessianInputReadObjectMethod extends Method {
UnsafeHessianInputReadObjectMethod() {
this.getDeclaringType().getASupertype*() instanceof UnsafeHessianInput and
this.getName() = "readObject"
}
}
/**
* The class `com.caucho.burlap.io.BurlapInput`.
*/
class BurlapInput extends RefType {
BurlapInput() { this.hasQualifiedName("com.caucho.burlap.io", "BurlapInput") }
}
/** A method with the name `readObject` declared in `com.caucho.burlap.io.BurlapInput`. */
class BurlapInputReadObjectMethod extends Method {
BurlapInputReadObjectMethod() {
this.getDeclaringType() instanceof BurlapInput and
this.getName() = "readObject"
}
}
/** A method with the name `init` declared in `com.caucho.burlap.io.BurlapInput`. */
class BurlapInputInitMethod extends Method {
BurlapInputInitMethod() {
this.getDeclaringType() instanceof BurlapInput and
this.getName() = "init"
}
}

View File

@@ -3,6 +3,7 @@
*/
import java
import semmle.code.java.dataflow.ExternalFlow
/** The interface `org.hibernate.query.QueryProducer`. */
class HibernateQueryProducer extends RefType {
@@ -21,19 +22,18 @@ class HibernateSession extends RefType {
HibernateSession() { this.hasQualifiedName("org.hibernate", "Session") }
}
/**
* Holds if `m` is a method on `HibernateQueryProducer`, or `HibernateSharedSessionContract`
* or `HibernateSession`, or a subclass, taking an SQL string as its first argument.
*/
predicate hibernateSqlMethod(Method m) {
exists(RefType t |
t = m.getDeclaringType().getASourceSupertype*() and
(
t instanceof HibernateQueryProducer or
t instanceof HibernateSharedSessionContract or
t instanceof HibernateSession
)
) and
m.getParameterType(0) instanceof TypeString and
m.hasName(["createQuery", "createNativeQuery", "createSQLQuery"])
private class SqlSinkCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;spec;kind"
"org.hibernate;QueryProducer;true;createQuery;;;Argument[0];sql",
"org.hibernate;QueryProducer;true;createNativeQuery;;;Argument[0];sql",
"org.hibernate;QueryProducer;true;createSQLQuery;;;Argument[0];sql",
"org.hibernate;SharedSessionContract;true;createQuery;;;Argument[0];sql",
"org.hibernate;SharedSessionContract;true;createSQLQuery;;;Argument[0];sql",
"org.hibernate;Session;true;createQuery;;;Argument[0];sql",
"org.hibernate;Session;true;createSQLQuery;;;Argument[0];sql"
]
}
}

View File

@@ -0,0 +1,22 @@
/**
* Provides classes and predicates for working with the JYaml framework.
*/
import java
/**
* The class `org.ho.yaml.Yaml` or `org.ho.yaml.YamlConfig`.
*/
class JYamlLoader extends RefType {
JYamlLoader() { this.hasQualifiedName("org.ho.yaml", ["Yaml", "YamlConfig"]) }
}
/**
* A JYaml unsafe load method, declared on either `Yaml` or `YamlConfig`.
*/
class JYamlLoaderUnsafeLoadMethod extends Method {
JYamlLoaderUnsafeLoadMethod() {
this.getDeclaringType() instanceof JYamlLoader and
this.getName() in ["load", "loadType", "loadStream", "loadStreamOfType"]
}
}

View File

@@ -137,6 +137,13 @@ class InterceptorsAnnotation extends Annotation {
* Annotations in the package `javax.jws`.
*/
/**
* A `@javax.jws.WebMethod` annotation.
*/
class WebMethodAnnotation extends Annotation {
WebMethodAnnotation() { this.getType().hasQualifiedName("javax.jws", "WebMethod") }
}
/**
* A `@javax.jws.WebService` annotation.
*/

View File

@@ -0,0 +1,138 @@
/**
* Provides models for the `javax.json` and `jakarta.json` packages.
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
private class FlowSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
["javax", "jakarta"] +
[
".json;Json;false;createArrayBuilder;(JsonArray);;Argument[0];ReturnValue;taint",
".json;Json;false;createArrayBuilder;(Collection);;Element of Argument[0];ReturnValue;taint",
".json;Json;false;createDiff;;;Argument[0..1];ReturnValue;taint",
".json;Json;false;createMergeDiff;;;Argument[0..1];ReturnValue;taint",
".json;Json;false;createMergePatch;;;Argument[0];ReturnValue;taint",
".json;Json;false;createObjectBuilder;(JsonObject);;Argument[0];ReturnValue;taint",
".json;Json;false;createObjectBuilder;(Map);;MapKey of Argument[0];ReturnValue;taint",
".json;Json;false;createObjectBuilder;(Map);;MapValue of Argument[0];ReturnValue;taint",
".json;Json;false;createPatch;;;Argument[0];ReturnValue;taint",
".json;Json;false;createPatchBuilder;;;Argument[0];ReturnValue;taint",
".json;Json;false;createPointer;;;Argument[0];ReturnValue;taint",
".json;Json;false;createReader;;;Argument[0];ReturnValue;taint",
".json;Json;false;createValue;;;Argument[0];ReturnValue;taint",
".json;Json;false;createWriter;;;Argument[0];ReturnValue;taint",
".json;Json;false;decodePointer;;;Argument[0];ReturnValue;taint",
".json;Json;false;encodePointer;;;Argument[0];ReturnValue;taint",
".json;JsonArray;false;getBoolean;;;Argument[-1];ReturnValue;taint",
".json;JsonArray;false;getBoolean;;;Argument[1];ReturnValue;value",
".json;JsonArray;false;getInt;;;Argument[-1];ReturnValue;taint",
".json;JsonArray;false;getInt;;;Argument[1];ReturnValue;value",
".json;JsonArray;false;getJsonArray;;;Argument[-1];ReturnValue;taint",
".json;JsonArray;false;getJsonNumber;;;Argument[-1];ReturnValue;taint",
".json;JsonArray;false;getJsonObject;;;Argument[-1];ReturnValue;taint",
".json;JsonArray;false;getJsonString;;;Argument[-1];ReturnValue;taint",
".json;JsonArray;false;getString;;;Argument[-1];ReturnValue;taint",
".json;JsonArray;false;getString;;;Argument[1];ReturnValue;value",
".json;JsonArray;false;getValuesAs;;;Argument[-1];ReturnValue;taint",
".json;JsonArrayBuilder;false;add;;;Argument[-1];ReturnValue;value",
".json;JsonArrayBuilder;false;add;(boolean);;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(double);;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int);;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(long);;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(JsonArrayBuilder);;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(JsonObjectBuilder);;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(JsonValue);;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(String);;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(BigDecimal);;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(BigInteger);;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int,boolean);;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int,double);;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int,int);;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int,long);;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int,JsonArrayBuilder);;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int,JsonObjectBuilder);;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int,JsonValue);;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int,String);;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int,BigDecimal);;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;add;(int,BigInteger);;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;addAll;;;Argument[0];Argument[-1];taint",
".json;JsonArrayBuilder;false;addAll;;;Argument[-1];ReturnValue;value",
".json;JsonArrayBuilder;false;addNull;;;Argument[-1];ReturnValue;value",
".json;JsonArrayBuilder;false;build;;;Argument[-1];ReturnValue;taint",
".json;JsonArrayBuilder;false;remove;;;Argument[-1];ReturnValue;value",
".json;JsonArrayBuilder;false;set;;;Argument[1];Argument[-1];taint",
".json;JsonArrayBuilder;false;set;;;Argument[-1];ReturnValue;value",
".json;JsonArrayBuilder;false;setNull;;;Argument[-1];ReturnValue;value",
".json;JsonMergePatch;false;apply;;;Argument[-1];ReturnValue;taint",
".json;JsonMergePatch;false;apply;;;Argument[0];ReturnValue;taint",
".json;JsonMergePatch;false;toJsonValue;;;Argument[-1];ReturnValue;taint",
".json;JsonNumber;false;bigDecimalValue;;;Argument[-1];ReturnValue;taint",
".json;JsonNumber;false;bigIntegerValue;;;Argument[-1];ReturnValue;taint",
".json;JsonNumber;false;bigIntegerValueExact;;;Argument[-1];ReturnValue;taint",
".json;JsonNumber;false;doubleValue;;;Argument[-1];ReturnValue;taint",
".json;JsonNumber;false;intValue;;;Argument[-1];ReturnValue;taint",
".json;JsonNumber;false;intValueExact;;;Argument[-1];ReturnValue;taint",
".json;JsonNumber;false;longValue;;;Argument[-1];ReturnValue;taint",
".json;JsonNumber;false;longValueExact;;;Argument[-1];ReturnValue;taint",
".json;JsonNumber;false;numberValue;;;Argument[-1];ReturnValue;taint",
".json;JsonObject;false;getBoolean;;;Argument[-1];ReturnValue;taint",
".json;JsonObject;false;getBoolean;;;Argument[1];ReturnValue;value",
".json;JsonObject;false;getInt;;;Argument[-1];ReturnValue;taint",
".json;JsonObject;false;getInt;;;Argument[1];ReturnValue;value",
".json;JsonObject;false;getJsonArray;;;Argument[-1];ReturnValue;taint",
".json;JsonObject;false;getJsonNumber;;;Argument[-1];ReturnValue;taint",
".json;JsonObject;false;getJsonObject;;;Argument[-1];ReturnValue;taint",
".json;JsonObject;false;getJsonString;;;Argument[-1];ReturnValue;taint",
".json;JsonObject;false;getString;;;Argument[-1];ReturnValue;taint",
".json;JsonObject;false;getString;;;Argument[1];ReturnValue;value",
".json;JsonObjectBuilder;false;add;;;Argument[-1];ReturnValue;value",
".json;JsonObjectBuilder;false;add;;;Argument[1];Argument[-1];taint",
".json;JsonObjectBuilder;false;addAll;;;Argument[0];ReturnValue;value",
".json;JsonObjectBuilder;false;addAll;;;Argument[-1];ReturnValue;value",
".json;JsonObjectBuilder;false;addNull;;;Argument[-1];ReturnValue;value",
".json;JsonObjectBuilder;false;build;;;Argument[-1];ReturnValue;taint",
".json;JsonObjectBuilder;false;remove;;;Argument[-1];ReturnValue;value",
".json;JsonPatch;false;apply;;;Argument[-1];ReturnValue;taint",
".json;JsonPatch;false;apply;;;Argument[0];ReturnValue;taint",
".json;JsonPatch;false;toJsonArray;;;Argument[-1];ReturnValue;taint",
".json;JsonPatchBuilder;false;add;;;Argument[0..1];ReturnValue;taint",
".json;JsonPatchBuilder;false;add;;;Argument[-1];ReturnValue;value",
".json;JsonPatchBuilder;false;build;;;Argument[-1];ReturnValue;taint",
".json;JsonPatchBuilder;false;copy;;;Argument[0..1];ReturnValue;taint",
".json;JsonPatchBuilder;false;copy;;;Argument[-1];ReturnValue;value",
".json;JsonPatchBuilder;false;move;;;Argument[0..1];ReturnValue;taint",
".json;JsonPatchBuilder;false;move;;;Argument[-1];ReturnValue;value",
".json;JsonPatchBuilder;false;remove;;;Argument[0];ReturnValue;taint",
".json;JsonPatchBuilder;false;remove;;;Argument[-1];ReturnValue;value",
".json;JsonPatchBuilder;false;replace;;;Argument[0..1];ReturnValue;taint",
".json;JsonPatchBuilder;false;replace;;;Argument[-1];ReturnValue;value",
".json;JsonPatchBuilder;false;test;;;Argument[0..1];ReturnValue;taint",
".json;JsonPatchBuilder;false;test;;;Argument[-1];ReturnValue;value",
".json;JsonPointer;false;add;;;Argument[-1];ReturnValue;taint",
".json;JsonPointer;false;add;;;Argument[0..1];ReturnValue;taint",
".json;JsonPointer;false;getValue;;;Argument[0];ReturnValue;taint",
".json;JsonPointer;false;remove;;;Argument[0];ReturnValue;taint",
".json;JsonPointer;false;replace;;;Argument[0..1];ReturnValue;taint",
".json;JsonPointer;false;toString;;;Argument[-1];ReturnValue;taint",
".json;JsonReader;false;read;;;Argument[-1];ReturnValue;taint",
".json;JsonReader;false;readArray;;;Argument[-1];ReturnValue;taint",
".json;JsonReader;false;readObject;;;Argument[-1];ReturnValue;taint",
".json;JsonReader;false;readValue;;;Argument[-1];ReturnValue;taint",
".json;JsonReaderFactory;false;createReader;;;Argument[0];ReturnValue;taint",
".json;JsonString;false;getChars;;;Argument[-1];ReturnValue;taint",
".json;JsonString;false;getString;;;Argument[-1];ReturnValue;taint",
".json;JsonStructure;true;getValue;;;Argument[-1];ReturnValue;taint",
".json;JsonValue;true;asJsonArray;;;Argument[-1];ReturnValue;taint",
".json;JsonValue;true;asJsonObject;;;Argument[-1];ReturnValue;taint",
".json;JsonValue;true;toString;;;Argument[-1];ReturnValue;taint",
".json;JsonWriter;false;write;;;Argument[0];Argument[-1];taint",
".json;JsonWriter;false;writeArray;;;Argument[0];Argument[-1];taint",
".json;JsonWriter;false;writeObject;;;Argument[0];Argument[-1];taint",
".json;JsonWriterFactory;false;createWriter;;;Argument[-1];Argument[0];taint",
".json.stream;JsonParserFactory;false;createParser;;;Argument[0];ReturnValue;taint"
]
}
}

View File

@@ -1,4 +1,22 @@
/**
* Definitions relating to JAX-WS (Java/Jakarta API for XML Web Services) and JAX-RS
* (Java/Jakarta API for RESTful Web Services).
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.security.XSS
/**
* Gets a name for the root package of JAX-RS.
*/
string getAJaxRsPackage() { result in ["javax.ws.rs", "jakarta.ws.rs"] }
/**
* Gets a name for package `subpackage` within the JAX-RS hierarchy.
*/
bindingset[subpackage]
string getAJaxRsPackage(string subpackage) { result = getAJaxRsPackage() + "." + subpackage }
/**
* A JAX WS endpoint is constructed by the container, and its methods
@@ -13,6 +31,7 @@ class JaxWsEndpoint extends Class {
)
}
/** Gets a method annotated with `@WebMethod` or `@WebEndpoint`. */
Callable getARemoteMethod() {
result = this.getACallable() and
exists(AnnotationType a | a = result.getAnAnnotation().getType() |
@@ -28,7 +47,7 @@ class JaxWsEndpoint extends Class {
private predicate hasPathAnnotation(Annotatable annotatable) {
exists(AnnotationType a |
a = annotatable.getAnAnnotation().getType() and
a.getPackage().getName() = "javax.ws.rs"
a.getPackage().getName() = getAJaxRsPackage()
|
a.hasName("Path")
)
@@ -41,7 +60,7 @@ class JaxRsResourceMethod extends Method {
JaxRsResourceMethod() {
exists(AnnotationType a |
a = this.getAnAnnotation().getType() and
a.getPackage().getName() = "javax.ws.rs"
a.getPackage().getName() = getAJaxRsPackage()
|
a.hasName("GET") or
a.hasName("POST") or
@@ -50,6 +69,27 @@ class JaxRsResourceMethod extends Method {
a.hasName("OPTIONS") or
a.hasName("HEAD")
)
or
// A JaxRS resource method can also inherit these annotations from a supertype, but only if
// there are no JaxRS annotations on the method itself
this.getAnOverride() instanceof JaxRsResourceMethod and
not exists(this.getAnAnnotation().(JaxRSAnnotation))
}
/** Gets an `@Produces` annotation that applies to this method */
JaxRSProducesAnnotation getProducesAnnotation() {
result = this.getAnAnnotation()
or
// No direct annotations
not this.getAnAnnotation() instanceof JaxRSProducesAnnotation and
(
// Annotations on a method we've overridden
result = this.getAnOverride().getAnAnnotation()
or
// No annotations on this method, or a method we've overridden, so look to the class
not this.getAnOverride().getAnAnnotation() instanceof JaxRSProducesAnnotation and
result = this.getDeclaringType().getAnAnnotation()
)
}
}
@@ -81,7 +121,7 @@ class JaxRsResourceClass extends Class {
* annotations leading to this resource method.
*/
JaxRsResourceMethod getAResourceMethod() {
isPublic() and
this.isPublic() and
result = this.getACallable()
}
@@ -90,7 +130,7 @@ class JaxRsResourceClass extends Class {
* but is not a resource method e.g. it is not annotated with `@GET` etc.
*/
Callable getASubResourceLocator() {
result = getAMethod() and
result = this.getAMethod() and
not result instanceof JaxRsResourceMethod and
hasPathAnnotation(result)
}
@@ -109,10 +149,10 @@ class JaxRsResourceClass extends Class {
* (existence of particular parameters).
*/
Constructor getAnInjectableConstructor() {
result = getAConstructor() and
result = this.getAConstructor() and
// JaxRs Spec v2.0 - 3.12
// Only root resources are constructed by the JaxRS container.
isRootResource() and
this.isRootResource() and
// JaxRS can only construct the class using constructors that are public, and where the
// container can provide all of the parameters. This includes the no-arg constructor.
result.isPublic() and
@@ -125,29 +165,41 @@ class JaxRsResourceClass extends Class {
* Gets a Callable that may be executed by the JaxRs container, injecting parameters as required.
*/
Callable getAnInjectableCallable() {
result = getAResourceMethod() or
result = getAnInjectableConstructor() or
result = getASubResourceLocator()
result = this.getAResourceMethod() or
result = this.getAnInjectableConstructor() or
result = this.getASubResourceLocator()
}
/**
* Gets a Field that may be injected with a value by the JaxRs container.
*/
Field getAnInjectableField() {
result = getAField() and
result = this.getAField() and
result.getAnAnnotation() instanceof JaxRsInjectionAnnotation
}
}
/**
* An annotation from the `javax.ws.rs` or `jakarta.ws.rs` package hierarchy.
*/
class JaxRSAnnotation extends Annotation {
JaxRSAnnotation() {
exists(AnnotationType a |
a = this.getType() and
a.getPackage().getName().regexpMatch(["javax\\.ws\\.rs(\\..*)?", "jakarta\\.ws\\.rs(\\..*)?"])
)
}
}
/**
* An annotation that is used by JaxRS containers to determine a value to inject into the annotated
* element.
*/
class JaxRsInjectionAnnotation extends Annotation {
class JaxRsInjectionAnnotation extends JaxRSAnnotation {
JaxRsInjectionAnnotation() {
exists(AnnotationType a |
a = getType() and
a.getPackage().getName() = "javax.ws.rs"
a = this.getType() and
a.getPackage().getName() = getAJaxRsPackage()
|
a.hasName("BeanParam") or
a.hasName("CookieParam") or
@@ -158,23 +210,31 @@ class JaxRsInjectionAnnotation extends Annotation {
a.hasName("QueryParam")
)
or
getType().hasQualifiedName("javax.ws.rs.core", "Context")
this.getType().hasQualifiedName(getAJaxRsPackage("core"), "Context")
}
}
/**
* The class `javax.ws.rs.core.Response`.
*/
class JaxRsResponse extends Class {
JaxRsResponse() { this.hasQualifiedName("javax.ws.rs.core", "Response") }
JaxRsResponse() { this.hasQualifiedName(getAJaxRsPackage("core"), "Response") }
}
/**
* The class `javax.ws.rs.core.Response$ResponseBuilder`.
*/
class JaxRsResponseBuilder extends Class {
JaxRsResponseBuilder() { this.hasQualifiedName("javax.ws.rs.core", "ResponseBuilder") }
JaxRsResponseBuilder() {
this.hasQualifiedName(getAJaxRsPackage("core"), "Response$ResponseBuilder")
}
}
/**
* The class `javax.ws.rs.client.Client`.
*/
class JaxRsClient extends RefType {
JaxRsClient() { this.hasQualifiedName("javax.ws.rs.client", "Client") }
JaxRsClient() { this.hasQualifiedName(getAJaxRsPackage("client"), "Client") }
}
/**
@@ -184,13 +244,12 @@ class JaxRsClient extends RefType {
class JaxRsBeanParamConstructor extends Constructor {
JaxRsBeanParamConstructor() {
exists(JaxRsResourceClass resourceClass, Callable c, Parameter p |
c = resourceClass.getAnInjectableCallable()
|
c = resourceClass.getAnInjectableCallable() and
p = c.getAParameter() and
p.getAnAnnotation().getType().hasQualifiedName("javax.ws.rs", "BeanParam") and
p.getAnAnnotation().getType().hasQualifiedName(getAJaxRsPackage(), "BeanParam") and
this.getDeclaringType().getSourceDeclaration() = p.getType().(RefType).getSourceDeclaration()
) and
forall(Parameter p | p = getAParameter() |
forall(Parameter p | p = this.getAParameter() |
p.getAnAnnotation() instanceof JaxRsInjectionAnnotation
)
}
@@ -200,7 +259,7 @@ class JaxRsBeanParamConstructor extends Constructor {
* The class `javax.ws.rs.ext.MessageBodyReader`.
*/
class MessageBodyReader extends GenericInterface {
MessageBodyReader() { this.hasQualifiedName("javax.ws.rs.ext", "MessageBodyReader") }
MessageBodyReader() { this.hasQualifiedName(getAJaxRsPackage("ext"), "MessageBodyReader") }
}
/**
@@ -208,7 +267,7 @@ class MessageBodyReader extends GenericInterface {
*/
class MessageBodyReaderReadFrom extends Method {
MessageBodyReaderReadFrom() {
this.getDeclaringType() instanceof MessageBodyReader and
this.getDeclaringType().getSourceDeclaration() instanceof MessageBodyReader and
this.hasName("readFrom")
}
}
@@ -223,3 +282,517 @@ class MessageBodyReaderRead extends Method {
)
}
}
/** An `@Produces` annotation that describes which content types can be produced by this resource. */
class JaxRSProducesAnnotation extends JaxRSAnnotation {
JaxRSProducesAnnotation() { this.getType().hasQualifiedName(getAJaxRsPackage(), "Produces") }
/**
* Gets a declared content type that can be produced by this resource.
*/
string getADeclaredContentType() {
result = this.getAValue().(CompileTimeConstantExpr).getStringValue()
or
exists(Field jaxMediaType |
// Accesses to static fields on `MediaType` class do not have constant strings in the database
// so convert the field name to a content type string
jaxMediaType.getDeclaringType().hasQualifiedName(getAJaxRsPackage("core"), "MediaType") and
jaxMediaType.getAnAccess() = this.getAValue() and
// e.g. MediaType.TEXT_PLAIN => text/plain
result = jaxMediaType.getName().toLowerCase().replaceAll("_", "/")
)
}
}
/** An `@Consumes` annotation that describes content types can be consumed by this resource. */
class JaxRSConsumesAnnotation extends JaxRSAnnotation {
JaxRSConsumesAnnotation() { this.getType().hasQualifiedName(getAJaxRsPackage(), "Consumes") }
}
/** A default sink representing methods susceptible to XSS attacks. */
private class JaxRSXssSink extends XssSink {
JaxRSXssSink() {
exists(JaxRsResourceMethod resourceMethod, ReturnStmt rs |
resourceMethod = any(JaxRsResourceClass resourceClass).getAResourceMethod() and
rs.getEnclosingCallable() = resourceMethod and
this.asExpr() = rs.getResult()
|
not exists(resourceMethod.getProducesAnnotation())
or
resourceMethod.getProducesAnnotation().getADeclaredContentType() = "text/plain"
)
}
}
/** A URL redirection sink from JAX-RS */
private class JaxRsUrlRedirectSink extends SinkModelCsv {
override predicate row(string row) {
row =
[
//`namespace; type; subtypes; name; signature; ext; input; kind`
"javax.ws.rs.core;Response;true;seeOther;;;Argument[0];url-redirect",
"javax.ws.rs.core;Response;true;temporaryRedirect;;;Argument[0];url-redirect",
"jakarta.ws.rs.core;Response;true;seeOther;;;Argument[0];url-redirect",
"jakarta.ws.rs.core;Response;true;temporaryRedirect;;;Argument[0];url-redirect"
]
}
}
/**
* Model Response:
*
* - the returned ResponseBuilder gains taint from a tainted entity or existing Response
*/
private class ResponseModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;Response;false;accepted;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;Response;false;fromResponse;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;Response;false;ok;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;Response;false;accepted;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;Response;false;fromResponse;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;Response;false;ok;;;Argument[0];ReturnValue;taint"
]
}
}
/**
* Model ResponseBuilder:
*
* - becomes tainted by a tainted entity, but not by metadata, headers etc
* - build() method returns taint
* - almost all methods are fluent, and so preserve value
*/
private class ResponseBuilderModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;Response$ResponseBuilder;true;build;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;Response$ResponseBuilder;true;entity;;;Argument[0];Argument[-1];taint",
"javax.ws.rs.core;Response$ResponseBuilder;true;allow;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;cacheControl;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;clone;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;Response$ResponseBuilder;true;contentLocation;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;cookie;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;encoding;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;entity;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;expires;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;header;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;language;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;lastModified;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;link;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;links;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;location;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;replaceAll;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;status;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;tag;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;type;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;variant;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;Response$ResponseBuilder;true;variants;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;build;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;entity;;;Argument[0];Argument[-1];taint",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;allow;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;cacheControl;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;clone;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;contentLocation;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;cookie;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;encoding;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;entity;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;expires;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;header;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;language;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;lastModified;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;link;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;links;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;location;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;replaceAll;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;status;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;tag;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;type;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;variant;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Response$ResponseBuilder;true;variants;;;Argument[-1];ReturnValue;value"
]
}
}
/**
* Model HttpHeaders: methods that Date have to be syntax-checked, but those returning MediaType
* or Locale are assumed potentially dangerous, as these types do not generally check that the
* input data is recognised, only that it conforms to the expected syntax.
*/
private class HttpHeadersModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;HttpHeaders;true;getAcceptableLanguages;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;HttpHeaders;true;getAcceptableMediaTypes;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;HttpHeaders;true;getCookies;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;HttpHeaders;true;getHeaderString;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;HttpHeaders;true;getLanguage;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;HttpHeaders;true;getMediaType;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;HttpHeaders;true;getRequestHeader;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;HttpHeaders;true;getRequestHeaders;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;HttpHeaders;true;getAcceptableLanguages;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;HttpHeaders;true;getAcceptableMediaTypes;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;HttpHeaders;true;getCookies;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;HttpHeaders;true;getHeaderString;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;HttpHeaders;true;getLanguage;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;HttpHeaders;true;getMediaType;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;HttpHeaders;true;getRequestHeader;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;HttpHeaders;true;getRequestHeaders;;;Argument[-1];ReturnValue;taint"
]
}
}
/**
* Model MultivaluedMap, which extends Map<K, List<V>> and provides a few extra helper methods.
*/
private class MultivaluedMapModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;MultivaluedMap;true;add;;;Argument[0];MapKey of Argument[-1];value",
"javax.ws.rs.core;MultivaluedMap;true;add;;;Argument[1];Element of MapValue of Argument[-1];value",
"javax.ws.rs.core;MultivaluedMap;true;addAll;;;Argument[0];MapKey of Argument[-1];value",
"javax.ws.rs.core;MultivaluedMap;true;addAll;(Object,List);;Element of Argument[1];Element of MapValue of Argument[-1];value",
"javax.ws.rs.core;MultivaluedMap;true;addAll;(Object,Object[]);;ArrayElement of Argument[1];Element of MapValue of Argument[-1];value",
"javax.ws.rs.core;MultivaluedMap;true;addFirst;;;Argument[0];MapKey of Argument[-1];value",
"javax.ws.rs.core;MultivaluedMap;true;addFirst;;;Argument[1];Element of MapValue of Argument[-1];value",
"javax.ws.rs.core;MultivaluedMap;true;getFirst;;;Element of MapValue of Argument[-1];ReturnValue;value",
"javax.ws.rs.core;MultivaluedMap;true;putSingle;;;Argument[0];MapKey of Argument[-1];value",
"javax.ws.rs.core;MultivaluedMap;true;putSingle;;;Argument[1];Element of MapValue of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedMap;true;add;;;Argument[0];MapKey of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedMap;true;add;;;Argument[1];Element of MapValue of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedMap;true;addAll;;;Argument[0];MapKey of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedMap;true;addAll;(Object,List);;Element of Argument[1];Element of MapValue of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedMap;true;addAll;(Object,Object[]);;ArrayElement of Argument[1];Element of MapValue of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedMap;true;addFirst;;;Argument[0];MapKey of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedMap;true;addFirst;;;Argument[1];Element of MapValue of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedMap;true;getFirst;;;Element of MapValue of Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;MultivaluedMap;true;putSingle;;;Argument[0];MapKey of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedMap;true;putSingle;;;Argument[1];Element of MapValue of Argument[-1];value"
]
}
}
/**
* Model AbstractMultivaluedMap, which implements MultivaluedMap.
*/
private class AbstractMultivaluedMapModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;AbstractMultivaluedMap;false;AbstractMultivaluedMap;;;MapKey of Argument[0];MapKey of Argument[-1];value",
"javax.ws.rs.core;AbstractMultivaluedMap;false;AbstractMultivaluedMap;;;MapValue of Argument[0];MapValue of Argument[-1];value",
"jakarta.ws.rs.core;AbstractMultivaluedMap;false;AbstractMultivaluedMap;;;MapKey of Argument[0];MapKey of Argument[-1];value",
"jakarta.ws.rs.core;AbstractMultivaluedMap;false;AbstractMultivaluedMap;;;MapValue of Argument[0];MapValue of Argument[-1];value"
]
}
}
/**
* Model MultivaluedHashMap, which extends AbstractMultivaluedMap.
*/
private class MultivaluedHashMapModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;MultivaluedHashMap;false;MultivaluedHashMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
"javax.ws.rs.core;MultivaluedHashMap;false;MultivaluedHashMap;(Map);;MapValue of Argument[0];Element of MapValue of Argument[-1];value",
"javax.ws.rs.core;MultivaluedHashMap;false;MultivaluedHashMap;(MultivaluedMap);;MapKey of Argument[0];MapKey of Argument[-1];value",
"javax.ws.rs.core;MultivaluedHashMap;false;MultivaluedHashMap;(MultivaluedMap);;MapValue of Argument[0];MapValue of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedHashMap;false;MultivaluedHashMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedHashMap;false;MultivaluedHashMap;(Map);;MapValue of Argument[0];Element of MapValue of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedHashMap;false;MultivaluedHashMap;(MultivaluedMap);;MapKey of Argument[0];MapKey of Argument[-1];value",
"jakarta.ws.rs.core;MultivaluedHashMap;false;MultivaluedHashMap;(MultivaluedMap);;MapValue of Argument[0];MapValue of Argument[-1];value"
]
}
}
/**
* Model PathSegment, which wraps a path and its associated matrix parameters.
*/
private class PathSegmentModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;PathSegment;true;getMatrixParameters;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;PathSegment;true;getPath;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;PathSegment;true;getMatrixParameters;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;PathSegment;true;getPath;;;Argument[-1];ReturnValue;taint"
]
}
}
/**
* Model UriInfo, which provides URI element accessors.
*/
private class UriInfoModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;UriInfo;true;getPathParameters;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;UriInfo;true;getPathSegments;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;UriInfo;true;getQueryParameters;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;UriInfo;true;getRequestUri;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;UriInfo;true;getRequestUriBuilder;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriInfo;true;getPathParameters;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriInfo;true;getPathSegments;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriInfo;true;getQueryParameters;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriInfo;true;getRequestUri;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriInfo;true;getRequestUriBuilder;;;Argument[-1];ReturnValue;taint"
]
}
}
/**
* Model Cookie, a simple tuple type.
*/
private class CookieModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;Cookie;true;getDomain;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;Cookie;true;getName;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;Cookie;true;getPath;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;Cookie;true;getValue;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;Cookie;true;getVersion;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;Cookie;true;toString;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;Cookie;false;Cookie;;;Argument[0..4];Argument[-1];taint",
"javax.ws.rs.core;Cookie;false;valueOf;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;Cookie;true;getDomain;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;Cookie;true;getName;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;Cookie;true;getPath;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;Cookie;true;getValue;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;Cookie;true;getVersion;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;Cookie;true;toString;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;Cookie;false;Cookie;;;Argument[0..4];Argument[-1];taint",
"jakarta.ws.rs.core;Cookie;false;valueOf;;;Argument[0];ReturnValue;taint"
]
}
}
/**
* Model NewCookie, a simple tuple type.
*/
private class NewCookieModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;NewCookie;true;getComment;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;NewCookie;true;getExpiry;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;NewCookie;true;getMaxAge;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;NewCookie;true;toCookie;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;NewCookie;false;NewCookie;;;Argument[0..9];Argument[-1];taint",
"javax.ws.rs.core;NewCookie;false;valueOf;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;NewCookie;true;getComment;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;NewCookie;true;getExpiry;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;NewCookie;true;getMaxAge;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;NewCookie;true;toCookie;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;NewCookie;false;NewCookie;;;Argument[0..9];Argument[-1];taint",
"jakarta.ws.rs.core;NewCookie;false;valueOf;;;Argument[0];ReturnValue;taint"
]
}
}
/**
* Model Form, a simple container type.
*/
private class FormModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;Form;false;Form;;;MapKey of Argument[0];Argument[-1];taint",
"javax.ws.rs.core;Form;false;Form;;;Element of MapValue of Argument[0];Argument[-1];taint",
"javax.ws.rs.core;Form;false;Form;;;Argument[0..1];Argument[-1];taint",
"javax.ws.rs.core;Form;true;asMap;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;Form;true;param;;;Argument[0..1];Argument[-1];taint",
"javax.ws.rs.core;Form;true;param;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;Form;false;Form;;;MapKey of Argument[0];Argument[-1];taint",
"jakarta.ws.rs.core;Form;false;Form;;;Element of MapValue of Argument[0];Argument[-1];taint",
"jakarta.ws.rs.core;Form;false;Form;;;Argument[0..1];Argument[-1];taint",
"jakarta.ws.rs.core;Form;true;asMap;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;Form;true;param;;;Argument[0..1];Argument[-1];taint",
"jakarta.ws.rs.core;Form;true;param;;;Argument[-1];ReturnValue;value"
]
}
}
/**
* Model GenericEntity, a wrapper for HTTP entities (e.g., documents).
*/
private class GenericEntityModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;GenericEntity;false;GenericEntity;;;Argument[0];Argument[-1];taint",
"javax.ws.rs.core;GenericEntity;true;getEntity;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;GenericEntity;false;GenericEntity;;;Argument[0];Argument[-1];taint",
"jakarta.ws.rs.core;GenericEntity;true;getEntity;;;Argument[-1];ReturnValue;taint"
]
}
}
/**
* Model MediaType, which provides accessors for elements of Content-Type and similar
* media type specifications.
*/
private class MediaTypeModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;MediaType;false;MediaType;;;Argument[0..2];Argument[-1];taint",
"javax.ws.rs.core;MediaType;true;getParameters;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;MediaType;true;getSubtype;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;MediaType;true;getType;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;MediaType;false;valueOf;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;MediaType;true;withCharset;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;MediaType;false;MediaType;;;Argument[0..2];Argument[-1];taint",
"jakarta.ws.rs.core;MediaType;true;getParameters;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;MediaType;true;getSubtype;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;MediaType;true;getType;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;MediaType;false;valueOf;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;MediaType;true;withCharset;;;Argument[-1];ReturnValue;taint"
]
}
}
/**
* Model UriBuilder, which provides a fluent interface to build a URI from components.
*/
private class UriBuilderModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.core;UriBuilder;true;build;;;ArrayElement of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;build;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;buildFromEncoded;;;ArrayElement of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;buildFromEncoded;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;buildFromEncodedMap;;;MapKey of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;buildFromEncodedMap;;;MapValue of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;buildFromEncodedMap;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;buildFromMap;;;MapKey of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;buildFromMap;;;MapValue of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;buildFromMap;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;clone;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;fragment;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;fragment;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;false;fromLink;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;false;fromPath;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;false;fromUri;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;host;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;host;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;matrixParam;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;matrixParam;;;ArrayElement of Argument[1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;matrixParam;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;path;;;Argument[0..1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;path;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;queryParam;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;queryParam;;;ArrayElement of Argument[1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;queryParam;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;replaceMatrix;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;replaceMatrix;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;replaceMatrixParam;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;replaceMatrixParam;;;ArrayElement of Argument[1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;replaceMatrixParam;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;replacePath;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;replacePath;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;replaceQuery;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;replaceQuery;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;replaceQueryParam;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;replaceQueryParam;;;ArrayElement of Argument[1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;replaceQueryParam;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;resolveTemplate;;;Argument[0..2];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;resolveTemplate;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;resolveTemplateFromEncoded;;;Argument[0..1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;resolveTemplateFromEncoded;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;resolveTemplates;;;MapKey of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;resolveTemplates;;;MapValue of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;resolveTemplates;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;resolveTemplatesFromEncoded;;;MapKey of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;resolveTemplatesFromEncoded;;;MapValue of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;resolveTemplatesFromEncoded;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;scheme;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;scheme;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;schemeSpecificPart;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;schemeSpecificPart;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;segment;;;ArrayElement of Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;segment;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;toTemplate;;;Argument[-1];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;uri;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;uri;;;Argument[-1];ReturnValue;value",
"javax.ws.rs.core;UriBuilder;true;userInfo;;;Argument[0];ReturnValue;taint",
"javax.ws.rs.core;UriBuilder;true;userInfo;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;build;;;ArrayElement of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;build;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;buildFromEncoded;;;ArrayElement of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;buildFromEncoded;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;buildFromEncodedMap;;;MapKey of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;buildFromEncodedMap;;;MapValue of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;buildFromEncodedMap;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;buildFromMap;;;MapKey of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;buildFromMap;;;MapValue of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;buildFromMap;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;clone;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;fragment;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;fragment;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;false;fromLink;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;false;fromPath;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;false;fromUri;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;host;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;host;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;matrixParam;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;matrixParam;;;ArrayElement of Argument[1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;matrixParam;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;path;;;Argument[0..1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;path;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;queryParam;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;queryParam;;;ArrayElement of Argument[1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;queryParam;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;replaceMatrix;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;replaceMatrix;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;replaceMatrixParam;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;replaceMatrixParam;;;ArrayElement of Argument[1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;replaceMatrixParam;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;replacePath;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;replacePath;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;replaceQuery;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;replaceQuery;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;replaceQueryParam;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;replaceQueryParam;;;ArrayElement of Argument[1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;replaceQueryParam;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;resolveTemplate;;;Argument[0..2];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;resolveTemplate;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;resolveTemplateFromEncoded;;;Argument[0..1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;resolveTemplateFromEncoded;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;resolveTemplates;;;MapKey of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;resolveTemplates;;;MapValue of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;resolveTemplates;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;resolveTemplatesFromEncoded;;;MapKey of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;resolveTemplatesFromEncoded;;;MapValue of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;resolveTemplatesFromEncoded;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;scheme;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;scheme;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;schemeSpecificPart;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;schemeSpecificPart;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;segment;;;ArrayElement of Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;segment;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;toTemplate;;;Argument[-1];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;uri;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;uri;;;Argument[-1];ReturnValue;value",
"jakarta.ws.rs.core;UriBuilder;true;userInfo;;;Argument[0];ReturnValue;taint",
"jakarta.ws.rs.core;UriBuilder;true;userInfo;;;Argument[-1];ReturnValue;value"
]
}
}
private class JaxRsUrlOpenSink extends SinkModelCsv {
override predicate row(string row) {
row =
[
"javax.ws.rs.client;Client;true;target;;;Argument[0];open-url",
"jakarta.ws.rs.client;Client;true;target;;;Argument[0];open-url"
]
}
}

View File

@@ -3,6 +3,7 @@
*/
import semmle.code.java.Type
import semmle.code.java.dataflow.ExternalFlow
/*--- Types ---*/
/** The interface `java.sql.Connection`. */
@@ -26,62 +27,6 @@ class TypeStatement extends Interface {
}
/*--- Methods ---*/
/** A method with the name `prepareStatement` declared in `java.sql.Connection`. */
class ConnectionPrepareStatement extends Method {
ConnectionPrepareStatement() {
getDeclaringType() instanceof TypeConnection and
hasName("prepareStatement")
}
}
/** A method with the name `prepareCall` declared in `java.sql.Connection`. */
class ConnectionPrepareCall extends Method {
ConnectionPrepareCall() {
getDeclaringType() instanceof TypeConnection and
hasName("prepareCall")
}
}
/** A method with the name `executeQuery` declared in `java.sql.Statement`. */
class StatementExecuteQuery extends Method {
StatementExecuteQuery() {
getDeclaringType() instanceof TypeStatement and
hasName("executeQuery")
}
}
/** A method with the name `execute` declared in `java.sql.Statement`. */
class MethodStatementExecute extends Method {
MethodStatementExecute() {
getDeclaringType() instanceof TypeStatement and
hasName("execute")
}
}
/** A method with the name `executeUpdate` declared in `java.sql.Statement`. */
class MethodStatementExecuteUpdate extends Method {
MethodStatementExecuteUpdate() {
getDeclaringType() instanceof TypeStatement and
hasName("executeUpdate")
}
}
/** A method with the name `executeLargeUpdate` declared in `java.sql.Statement`. */
class MethodStatementExecuteLargeUpdate extends Method {
MethodStatementExecuteLargeUpdate() {
getDeclaringType() instanceof TypeStatement and
hasName("executeLargeUpdate")
}
}
/** A method with the name `addBatch` declared in `java.sql.Statement`. */
class MethodStatementAddBatch extends Method {
MethodStatementAddBatch() {
getDeclaringType() instanceof TypeStatement and
hasName("addBatch")
}
}
/** A method with the name `getString` declared in `java.sql.ResultSet`. */
class ResultSetGetStringMethod extends Method {
ResultSetGetStringMethod() {
@@ -92,24 +37,18 @@ class ResultSetGetStringMethod extends Method {
}
/*--- Other definitions ---*/
/**
* An expression representing SQL code that occurs as an argument of
* a method in `java.sql.Connection` or `java.sql.Statement`.
*/
class SqlExpr extends Expr {
SqlExpr() {
exists(MethodAccess call, Method method |
call.getArgument(0) = this and
method = call.getMethod() and
(
method instanceof ConnectionPrepareStatement or
method instanceof ConnectionPrepareCall or
method instanceof StatementExecuteQuery or
method instanceof MethodStatementExecute or
method instanceof MethodStatementExecuteUpdate or
method instanceof MethodStatementExecuteLargeUpdate or
method instanceof MethodStatementAddBatch
)
)
private class SqlSinkCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;spec;kind"
"java.sql;Connection;true;prepareStatement;;;Argument[0];sql",
"java.sql;Connection;true;prepareCall;;;Argument[0];sql",
"java.sql;Statement;true;execute;;;Argument[0];sql",
"java.sql;Statement;true;executeQuery;;;Argument[0];sql",
"java.sql;Statement;true;executeUpdate;;;Argument[0];sql",
"java.sql;Statement;true;executeLargeUpdate;;;Argument[0];sql",
"java.sql;Statement;true;addBatch;;;Argument[0];sql"
]
}
}

View File

@@ -0,0 +1,67 @@
/**
* Provides classes and predicates for working with the Json-io framework.
*/
import java
import semmle.code.java.Maps
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.DataFlow2
/**
* The class `com.cedarsoftware.util.io.JsonReader`.
*/
class JsonIoJsonReader extends RefType {
JsonIoJsonReader() { this.hasQualifiedName("com.cedarsoftware.util.io", "JsonReader") }
}
/** A method with the name `jsonToJava` declared in `com.cedarsoftware.util.io.JsonReader`. */
class JsonIoJsonToJavaMethod extends Method {
JsonIoJsonToJavaMethod() {
this.getDeclaringType() instanceof JsonIoJsonReader and
this.getName() = "jsonToJava"
}
}
/** A method with the name `readObject` declared in `com.cedarsoftware.util.io.JsonReader`. */
class JsonIoReadObjectMethod extends Method {
JsonIoReadObjectMethod() {
this.getDeclaringType() instanceof JsonIoJsonReader and
this.getName() = "readObject"
}
}
/**
* A call to `Map.put` method, set the value of the `USE_MAPS` key to `true`.
*/
class JsonIoUseMapsSetter extends MethodAccess {
JsonIoUseMapsSetter() {
this.getMethod().getDeclaringType().getASourceSupertype*() instanceof MapType and
this.getMethod().hasName("put") and
this.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "USE_MAPS" and
this.getArgument(1).(CompileTimeConstantExpr).getBooleanValue() = true
}
}
/** A data flow configuration tracing flow from JsonIo safe settings. */
class SafeJsonIoConfig extends DataFlow2::Configuration {
SafeJsonIoConfig() { this = "UnsafeDeserialization::SafeJsonIoConfig" }
override predicate isSource(DataFlow::Node src) {
exists(MethodAccess ma |
ma instanceof JsonIoUseMapsSetter and
src.asExpr() = ma.getQualifier()
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof JsonIoJsonToJavaMethod and
sink.asExpr() = ma.getArgument(1)
)
or
exists(ClassInstanceExpr cie |
cie.getConstructor().getDeclaringType() instanceof JsonIoJsonReader and
sink.asExpr() = cie.getArgument(1)
)
}
}

View File

@@ -3,25 +3,24 @@
*/
import java
import semmle.code.java.dataflow.ExternalFlow
/** The class `org.apache.ibatis.jdbc.SqlRunner`. */
class MyBatisSqlRunner extends RefType {
MyBatisSqlRunner() { this.hasQualifiedName("org.apache.ibatis.jdbc", "SqlRunner") }
}
/**
* Holds if `m` is a method on `MyBatisSqlRunner` taking an SQL string as its
* first argument.
*/
predicate mybatisSqlMethod(Method m) {
m.getDeclaringType() instanceof MyBatisSqlRunner and
m.getParameterType(0) instanceof TypeString and
(
m.hasName("delete") or
m.hasName("insert") or
m.hasName("run") or
m.hasName("selectAll") or
m.hasName("selectOne") or
m.hasName("update")
)
private class SqlSinkCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;spec;kind"
"org.apache.ibatis.jdbc;SqlRunner;false;delete;(String,Object[]);;Argument[0];sql",
"org.apache.ibatis.jdbc;SqlRunner;false;insert;(String,Object[]);;Argument[0];sql",
"org.apache.ibatis.jdbc;SqlRunner;false;run;(String);;Argument[0];sql",
"org.apache.ibatis.jdbc;SqlRunner;false;selectAll;(String,Object[]);;Argument[0];sql",
"org.apache.ibatis.jdbc;SqlRunner;false;selectOne;(String,Object[]);;Argument[0];sql",
"org.apache.ibatis.jdbc;SqlRunner;false;update;(String,Object[]);;Argument[0];sql"
]
}
}

View File

@@ -0,0 +1,21 @@
/** Definitions related to `java.util.Optional`. */
import semmle.code.java.dataflow.ExternalFlow
private class OptionalModel extends SummaryModelCsv {
override predicate row(string s) {
s =
[
"java.util;Optional;false;filter;;;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Optional;false;get;;;Element of Argument[-1];ReturnValue;value",
"java.util;Optional;false;of;;;Argument[0];Element of ReturnValue;value",
"java.util;Optional;false;ofNullable;;;Argument[0];Element of ReturnValue;value",
"java.util;Optional;false;or;;;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Optional;false;orElse;;;Element of Argument[-1];ReturnValue;value",
"java.util;Optional;false;orElse;;;Argument[0];ReturnValue;value",
"java.util;Optional;false;orElseGet;;;Element of Argument[-1];ReturnValue;value",
"java.util;Optional;false;orElseThrow;;;Element of Argument[-1];ReturnValue;value",
"java.util;Optional;false;stream;;;Element of Argument[-1];Element of ReturnValue;value"
]
}
}

View File

@@ -3,33 +3,37 @@
*/
import java
import semmle.code.java.dataflow.ExternalFlow
/** The class `org.springframework.jdbc.core.JdbcTemplate`. */
class JdbcTemplate extends RefType {
JdbcTemplate() { this.hasQualifiedName("org.springframework.jdbc.core", "JdbcTemplate") }
}
/**
* Holds if `m` is a method on `JdbcTemplate` taking an SQL string as its first
* argument.
*/
predicate jdbcSqlMethod(Method m) {
m.getDeclaringType() instanceof JdbcTemplate and
m.getParameterType(0) instanceof TypeString and
(
m.hasName("batchUpdate") or
m.hasName("execute") or
m.getName().matches("query%") or
m.hasName("update")
)
}
/** The method `JdbcTemplate.batchUpdate(String... sql)` */
class BatchUpdateVarargsMethod extends Method {
BatchUpdateVarargsMethod() {
this.getDeclaringType() instanceof JdbcTemplate and
this.hasName("batchUpdate") and
this.getParameterType(0).(Array).getComponentType() instanceof TypeString and
this.getParameter(0).isVarargs()
private class SqlSinkCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;spec;kind"
"org.springframework.jdbc.core;JdbcTemplate;false;batchUpdate;(String[]);;Argument[0];sql",
"org.springframework.jdbc.core;JdbcTemplate;false;batchUpdate;;;Argument[0];sql",
"org.springframework.jdbc.core;JdbcTemplate;false;execute;;;Argument[0];sql",
"org.springframework.jdbc.core;JdbcTemplate;false;update;;;Argument[0];sql",
"org.springframework.jdbc.core;JdbcTemplate;false;query;;;Argument[0];sql",
"org.springframework.jdbc.core;JdbcTemplate;false;queryForList;;;Argument[0];sql",
"org.springframework.jdbc.core;JdbcTemplate;false;queryForMap;;;Argument[0];sql",
"org.springframework.jdbc.core;JdbcTemplate;false;queryForObject;;;Argument[0];sql",
"org.springframework.jdbc.core;JdbcTemplate;false;queryForRowSet;;;Argument[0];sql",
"org.springframework.jdbc.core;JdbcTemplate;false;queryForStream;;;Argument[0];sql",
"org.springframework.jdbc.object;BatchSqlUpdate;false;BatchSqlUpdate;;;Argument[1];sql",
"org.springframework.jdbc.object;MappingSqlQuery;false;BatchSqlUpdate;;;Argument[1];sql",
"org.springframework.jdbc.object;MappingSqlQueryWithParameters;false;BatchSqlUpdate;;;Argument[1];sql",
"org.springframework.jdbc.object;RdbmsOperation;true;setSql;;;Argument[0];sql",
"org.springframework.jdbc.object;SqlCall;false;SqlCall;;;Argument[1];sql",
"org.springframework.jdbc.object;SqlFunction;false;SqlFunction;;;Argument[1];sql",
"org.springframework.jdbc.object;SqlQuery;false;SqlQuery;;;Argument[1];sql",
"org.springframework.jdbc.object;SqlUpdate;false;SqlUpdate;;;Argument[1];sql",
"org.springframework.jdbc.object;UpdatableSqlQuery;false;UpdatableSqlQuery;;;Argument[1];sql"
]
}
}

View File

@@ -0,0 +1,20 @@
/**
* Provides classes and predicates for working with the YamlBeans framework.
*/
import java
/**
* The class `com.esotericsoftware.yamlbeans.YamlReader`.
*/
class YamlBeansReader extends RefType {
YamlBeansReader() { this.hasQualifiedName("com.esotericsoftware.yamlbeans", "YamlReader") }
}
/** A method with the name `read` declared in `com.esotericsoftware.yamlbeans.YamlReader`. */
class YamlBeansReaderReadMethod extends Method {
YamlBeansReaderReadMethod() {
this.getDeclaringType() instanceof YamlBeansReader and
this.getName() = "read"
}
}

View File

@@ -1,6 +1,7 @@
import java
import Android
import semmle.code.java.dataflow.FlowSteps
import semmle.code.java.dataflow.ExternalFlow
/**
* The class `android.database.sqlite.SQLiteDatabase`.
@@ -23,277 +24,137 @@ class TypeDatabaseUtils extends Class {
TypeDatabaseUtils() { hasQualifiedName("android.database", "DatabaseUtils") }
}
abstract class SQLiteRunner extends Method {
abstract int sqlIndex();
}
private class ExecSqlMethod extends SQLiteRunner {
ExecSqlMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
// execPerConnectionSQL(String sql, Object[] bindArgs)
// execSQL(String sql)
// execSQL(String sql, Object[] bindArgs)
this.hasName(["execPerConnectionSQL", "execSQL"])
}
override int sqlIndex() { result = 0 }
}
private class QueryMethod extends SQLiteRunner {
QueryMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
this.hasName(["query", "queryWithFactory"])
}
override int sqlIndex() {
// query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
// query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)
// query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
// query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
this.getName() = "query" and
(
if this.getParameter(0).getType() instanceof TypeString
then result = [0, 1, 2, 4, 5, 6, 7]
else result = [1, 2, 3, 5, 6, 7, 8]
)
or
// queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)
// queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
this.getName() = "queryWithFactory" and result = [2, 3, 4, 6, 7, 8, 9]
private class SQLiteSinkCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;spec;kind"
"android.database.sqlite;SQLiteDatabase;false;compileStatement;(String);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;execSQL;(String);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;execSQL;(String,Object[]);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;execPerConnectionSQL;(String,Object[]);;Argument[0];sql",
// query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
// query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)
// query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
// query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
// queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)
// queryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
// Each String / String[] arg except for selectionArgs is a sink
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[1];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String,String);;Argument[4..7];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String);;Argument[0..2];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(String,String[],String,String[],String,String,String);;Argument[4..6];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[1];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[3];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String);;Argument[5..8];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[1];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[3];sql",
"android.database.sqlite;SQLiteDatabase;false;query;(boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[5..8];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[3];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[4];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String);;Argument[6..9];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[3];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[4];sql",
"android.database.sqlite;SQLiteDatabase;false;queryWithFactory;(CursorFactory,boolean,String,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[6..9];sql",
"android.database.sqlite;SQLiteDatabase;false;rawQuery;(String,String[]);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;rawQuery;(String,String[],CancellationSignal);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;rawQueryWithFactory;(CursorFactory,String,String[],String);;Argument[1];sql",
"android.database.sqlite;SQLiteDatabase;false;rawQueryWithFactory;(CursorFactory,String,String[],String,CancellationSignal);;Argument[1];sql",
"android.database.sqlite;SQLiteDatabase;false;delete;(String,String,String[]);;Argument[0..1];sql",
"android.database.sqlite;SQLiteDatabase;false;update;(String,ContentValues,String,String[]);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;update;(String,ContentValues,String,String[]);;Argument[2];sql",
"android.database.sqlite;SQLiteDatabase;false;updateWithOnConflict;(String,ContentValues,String,String[],int);;Argument[0];sql",
"android.database.sqlite;SQLiteDatabase;false;updateWithOnConflict;(String,ContentValues,String,String[],int);;Argument[2];sql",
"android.database;DatabaseUtils;false;longForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql",
"android.database;DatabaseUtils;false;stringForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql",
"android.database;DatabaseUtils;false;blobFileDescriptorForQuery;(SQLiteDatabase,String,String[]);;Argument[1];sql",
"android.database;DatabaseUtils;false;createDbFromSqlStatements;(Context,String,int,String);;Argument[3];sql",
"android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String);;Argument[1];sql",
"android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String,String);;Argument[1..2];sql",
"android.database;DatabaseUtils;false;queryNumEntries;(SQLiteDatabase,String,String,String[]);;Argument[1..2];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;delete;(SQLiteDatabase,String,String[]);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;delete;(SQLiteDatabase,String,String[]);;Argument[1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;insert;(SQLiteDatabase,ContentValues);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;update;(SQLiteDatabase,ContentValues,String,String[]);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;update;(SQLiteDatabase,ContentValues,String,String[]);;Argument[2];sql",
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder)
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit)
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit, CancellationSignal cancellationSignal)
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[2];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String);;Argument[4..6];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[2];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String);;Argument[4..7];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[-1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[1];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[2];sql",
"android.database.sqlite;SQLiteQueryBuilder;true;query;(SQLiteDatabase,String[],String,String[],String,String,String,String,CancellationSignal);;Argument[4..7];sql",
"android.content;ContentProvider;true;delete;(Uri,String,String[]);;Argument[1];sql",
"android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Argument[2];sql",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[2];sql",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Argument[2];sql",
"android.content;ContentResolver;true;delete;(Uri,String,String[]);;Argument[1];sql",
"android.content;ContentResolver;true;update;(Uri,ContentValues,String,String[]);;Argument[2];sql",
"android.content;ContentResolver;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[2];sql",
"android.content;ContentResolver;true;query;(Uri,String[],String,String[],String);;Argument[2];sql"
]
}
}
private class RawQueryMethod extends SQLiteRunner {
RawQueryMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
this.hasName(["rawQuery", "rawQueryWithFactory"])
}
override int sqlIndex() {
// rawQuery(String sql, String[] selectionArgs, CancellationSignal cancellationSignal)
// rawQuery(String sql, String[] selectionArgs)
this.getName() = "rawQuery" and result = 0
or
// rawQueryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable, CancellationSignal cancellationSignal)
// rawQueryWithFactory(SQLiteDatabase.CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable)
this.getName() = "rawQueryWithFactory" and result = 1
private class SqlFlowStep extends SummaryModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;inputspec;outputspec;kind",
// buildQuery(String[] projectionIn, String selection, String groupBy, String having, String sortOrder, String limit)
// buildQuery(String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit)
// buildUnionQuery(String[] subQueries, String sortOrder, String limit)
"android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String,String,String,String);;Argument[-1];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String,String,String,String);;ArrayElement of Argument[0];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String,String,String,String);;Argument[1..5];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[-1];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;ArrayElement of Argument[0];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[1];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildQuery;(String[],String,String[],String,String,String,String);;Argument[3..6];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionQuery;(String[],String,String);;Argument[-1];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionQuery;(String[],String,String);;ArrayElement of Argument[0];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionQuery;(String[],String,String);;Argument[1..2];ReturnValue;taint",
// buildUnionSubQuery(String typeDiscriminatorColumn, String[] unionColumns, Set<String> columnsPresentInTable, int computedColumnsOffset, String typeDiscriminatorValue, String selection, String[] selectionArgs, String groupBy, String having)
// buildUnionSubQuery(String typeDiscriminatorColumn, String[] unionColumns, Set<String> columnsPresentInTable, int computedColumnsOffset, String typeDiscriminatorValue, String selection, String groupBy, String having)
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[-1..0];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;ArrayElement of Argument[1];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Element of Argument[2];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[4..5];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String[],String,String);;Argument[7..8];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Argument[-1..0];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;ArrayElement of Argument[1];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Element of Argument[2];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildUnionSubQuery;(String,String[],Set,int,String,String,String,String);;Argument[4..7];ReturnValue;taint",
// static buildQueryString(boolean distinct, String tables, String[] columns, String where, String groupBy, String having, String orderBy, String limit)
"android.database.sqlite;SQLiteQueryBuilder;true;buildQueryString;(boolean,String,String[],String,String,String,String,String);;Argument[1];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildQueryString;(boolean,String,String[],String,String,String,String,String);;ArrayElement of Argument[2];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;buildQueryString;(boolean,String,String[],String,String,String,String,String);;Argument[3..7];ReturnValue;taint",
"android.database.sqlite;SQLiteQueryBuilder;true;setProjectionMap;(Map);;MapKey of Argument[0];Argument[-1];taint",
"android.database.sqlite;SQLiteQueryBuilder;true;setProjectionMap;(Map);;MapValue of Argument[0];Argument[-1];taint",
"android.database.sqlite;SQLiteQueryBuilder;true;setTables;(String);;Argument[0];Argument[-1];taint",
"android.database.sqlite;SQLiteQueryBuilder;true;appendWhere;(CharSequence);;Argument[0];Argument[-1];taint",
"android.database.sqlite;SQLiteQueryBuilder;true;appendWhereStandalone;(CharSequence);;Argument[0];Argument[-1];taint",
"android.database.sqlite;SQLiteQueryBuilder;true;appendColumns;(StringBuilder,String[]);;ArrayElement of Argument[1];Argument[0];taint",
"android.database;DatabaseUtils;false;appendSelectionArgs;(String[],String[]);;ArrayElement of Argument[0..1];ArrayElement of ReturnValue;taint",
"android.database;DatabaseUtils;false;concatenateWhere;(String,String);;Argument[0..1];ReturnValue;taint",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Argument[0];ReturnValue;taint",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[0];ReturnValue;taint",
"android.content;ContentResolver;true;query;(Uri,String[],String,String[],String);;Argument[0];ReturnValue;taint",
"android.content;ContentResolver;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Argument[0];ReturnValue;taint"
]
}
}
private class CompileStatementMethod extends SQLiteRunner {
CompileStatementMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
// compileStatement(String sql)
this.hasName("compileStatement")
}
override int sqlIndex() { result = 0 }
}
private class DeleteMethod extends SQLiteRunner {
DeleteMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
// delete(String table, String whereClause, String[] whereArgs)
this.hasName("delete")
}
override int sqlIndex() { result = 1 }
}
private class UpdateMethod extends SQLiteRunner {
UpdateMethod() {
this.getDeclaringType() instanceof TypeSQLiteDatabase and
// update(String table, ContentValues values, String whereClause, String[] whereArgs)
// updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, int conflictAlgorithm)
this.hasName(["update", "updateWithOnConflict"])
}
override int sqlIndex() { result = 2 }
}
private class ForQueryMethod extends SQLiteRunner {
ForQueryMethod() {
// (blobFileDescriptor|long|string)ForQuery(SQLiteDatabase db, String query, String[] selectionArgs)
this.getDeclaringType() instanceof TypeDatabaseUtils and
this.hasName(["blobFileDescriptorForQuery", "longForQuery", "stringForQuery"]) and
this.getNumberOfParameters() = 3
}
override int sqlIndex() { result = 1 }
}
private class CreateDbFromSqlStatementsMethod extends SQLiteRunner {
CreateDbFromSqlStatementsMethod() {
// createDbFromSqlStatements(Context context, String dbName, int dbVersion, String sqlStatements)
this.getDeclaringType() instanceof TypeDatabaseUtils and
this.hasName("createDbFromSqlStatements")
}
override int sqlIndex() { result = 3 }
}
private class QueryNumEntriesMethod extends SQLiteRunner {
QueryNumEntriesMethod() {
// queryNumEntries(SQLiteDatabase db, String table, String selection)
// queryNumEntries(SQLiteDatabase db, String table, String selection, String[] selectionArgs)
this.getDeclaringType() instanceof TypeDatabaseUtils and
this.hasName("queryNumEntries")
}
override int sqlIndex() { result = 2 }
}
private class QueryBuilderDeleteMethod extends SQLiteRunner {
QueryBuilderDeleteMethod() {
// delete(SQLiteDatabase db, String selection, String[] selectionArgs)
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
this.hasName("delete")
}
override int sqlIndex() { result = [-1, 1] }
}
private class QueryBuilderInsertMethod extends SQLiteRunner {
QueryBuilderInsertMethod() {
// insert(SQLiteDatabase db, ContentValues values)
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
this.hasName("insert")
}
override int sqlIndex() { result = -1 }
}
private class QueryBuilderQueryMethod extends SQLiteRunner {
QueryBuilderQueryMethod() {
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder)
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit)
// query(SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit, CancellationSignal cancellationSignal)
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
this.hasName("query")
}
override int sqlIndex() { result = [-1, 2, 4, 5, 6, 7] }
}
private class QueryBuilderUpdateMethod extends SQLiteRunner {
QueryBuilderUpdateMethod() {
// update(SQLiteDatabase db, ContentValues values, String selection, String[] selectionArgs)
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
this.hasName("update")
}
override int sqlIndex() { result = [-1, 2] }
}
private class ContentProviderDeleteMethod extends SQLiteRunner {
ContentProviderDeleteMethod() {
// delete(Uri uri, String selection, String[] selectionArgs)
(
this.getDeclaringType() instanceof AndroidContentProvider or
this.getDeclaringType() instanceof AndroidContentResolver
) and
this.hasName("delete") and
this.getNumberOfParameters() = 3
}
override int sqlIndex() { result = 1 }
}
private class ContentProviderQueryMethod extends SQLiteRunner {
ContentProviderQueryMethod() {
// query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)
// query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
(
this.getDeclaringType() instanceof AndroidContentProvider or
this.getDeclaringType() instanceof AndroidContentResolver
) and
this.hasName("query") and
this.getNumberOfParameters() = [5, 6]
}
override int sqlIndex() { result = 2 }
}
private class ContentProviderUpdateMethod extends SQLiteRunner {
ContentProviderUpdateMethod() {
// update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
(
this.getDeclaringType() instanceof AndroidContentProvider or
this.getDeclaringType() instanceof AndroidContentResolver
) and
this.hasName("update") and
this.getNumberOfParameters() = 4
}
override int sqlIndex() { result = 2 }
}
private class QueryBuilderBuildMethod extends TaintPreservingCallable {
int argument;
QueryBuilderBuildMethod() {
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
(
// buildQuery(String[] projectionIn, String selection, String groupBy, String having, String sortOrder, String limit)
// buildQuery(String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit)
// buildUnionQuery(String[] subQueries, String sortOrder, String limit)
this.hasName(["buildQuery", "buildUnionQuery"]) and
argument = [-1 .. getNumberOfParameters()]
or
// buildUnionSubQuery(String typeDiscriminatorColumn, String[] unionColumns, Set<String> columnsPresentInTable, int computedColumnsOffset, String typeDiscriminatorValue, String selection, String[] selectionArgs, String groupBy, String having)
// buildUnionSubQuery(String typeDiscriminatorColumn, String[] unionColumns, Set<String> columnsPresentInTable, int computedColumnsOffset, String typeDiscriminatorValue, String selection, String groupBy, String having)
this.hasName("buildUnionSubQuery") and
argument = [-1 .. getNumberOfParameters()] and
argument != 3
or
// static buildQueryString(boolean distinct, String tables, String[] columns, String where, String groupBy, String having, String orderBy, String limit)
hasName("buildQueryString") and
argument = [1 .. getNumberOfParameters()]
)
}
override predicate returnsTaintFrom(int arg) { argument = arg }
}
private class QueryBuilderAppendMethod extends TaintPreservingCallable {
QueryBuilderAppendMethod() {
this.getDeclaringType().getASourceSupertype*() instanceof TypeSQLiteQueryBuilder and
// setProjectionMap(Map<String, String> columnMap)
// setTables(String inTables)
// appendWhere(CharSequence inWhere)
// appendWhereStandalone(CharSequence inWhere)
// static appendColumns(StringBuilder s, String[] columns)
this.hasName([
"setProjectionMap", "setTables", "appendWhere", "appendWhereStandalone", "appendColumns"
])
}
override predicate transfersTaint(int src, int sink) {
if hasName("appendColumns") then (src = 1 and sink = 0) else (src = 0 and sink = -1)
}
}
private class UnsafeAppendUtilMethod extends TaintPreservingCallable {
UnsafeAppendUtilMethod() {
this.getDeclaringType() instanceof TypeDatabaseUtils and
// String[] appendSelectionArgs(String[] originalValues, String[] newValues)
// String concatenateWhere(String a, String b)
this.hasName(["appendSelectionArgs", "concatenateWhere"])
}
override predicate returnsTaintFrom(int arg) { arg = [0 .. getNumberOfParameters()] }
}
private class TaintPreservingQueryMethod extends TaintPreservingCallable {
TaintPreservingQueryMethod() {
(
this.getDeclaringType() instanceof AndroidContentProvider or
this.getDeclaringType() instanceof AndroidContentResolver
) and
// Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, CancellationSignal cancellationSignal)
// Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
this.hasName("query")
}
override predicate returnsTaintFrom(int arg) { arg = 0 }
}

View File

@@ -0,0 +1,16 @@
/** Provides XSS sink models relating to the `android.webkit.WebView` class. */
import java
private import semmle.code.java.dataflow.ExternalFlow
/** CSV sink models representing methods susceptible to XSS attacks. */
private class DefaultXssSinkModel extends SinkModelCsv {
override predicate row(string row) {
row =
[
"android.webkit;WebView;false;loadData;;;Argument[0];xss",
"android.webkit;WebView;false;loadUrl;;;Argument[0];xss",
"android.webkit;WebView;false;loadDataWithBaseURL;;;Argument[1];xss"
]
}
}

View File

@@ -0,0 +1,264 @@
/** Definitions related to the Apache Commons Collections library. */
import java
private import semmle.code.java.dataflow.FlowSteps
private import semmle.code.java.dataflow.ExternalFlow
/**
* The method `isNotEmpty` in either `org.apache.commons.collections.CollectionUtils`
* or `org.apache.commons.collections4.CollectionUtils`.
*/
class MethodApacheCollectionsIsEmpty extends Method {
MethodApacheCollectionsIsEmpty() {
this.getDeclaringType()
.hasQualifiedName(["org.apache.commons.collections", "org.apache.commons.collections4"],
"CollectionUtils") and
this.hasName("isEmpty")
}
}
/**
* The method `isNotEmpty` in either `org.apache.commons.collections.CollectionUtils`
* or `org.apache.commons.collections4.CollectionUtils`.
*/
class MethodApacheCollectionsIsNotEmpty extends Method {
MethodApacheCollectionsIsNotEmpty() {
this.getDeclaringType()
.hasQualifiedName(["org.apache.commons.collections", "org.apache.commons.collections4"],
"CollectionUtils") and
this.hasName("isNotEmpty")
}
}
/**
* Value-propagating models for classes in the package `org.apache.commons.collections4`.
*/
private class ApacheCollectionsModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.collections4;KeyValue;true;getKey;;;MapKey of Argument[-1];ReturnValue;value",
"org.apache.commons.collections4;KeyValue;true;getValue;;;MapValue of Argument[-1];ReturnValue;value",
"org.apache.commons.collections;KeyValue;true;getKey;;;MapKey of Argument[-1];ReturnValue;value",
"org.apache.commons.collections;KeyValue;true;getValue;;;MapValue of Argument[-1];ReturnValue;value"
]
}
}
/**
* Value-propagating models for classes in the package `org.apache.commons.collections4.keyvalue`.
*/
private class ApacheKeyValueModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.collections4.keyvalue;AbstractKeyValue;true;AbstractKeyValue;;;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;AbstractKeyValue;true;AbstractKeyValue;;;Argument[1];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;AbstractKeyValue;true;setKey;;;MapValue of Argument[-1];ReturnValue;value",
"org.apache.commons.collections4.keyvalue;AbstractKeyValue;true;setKey;;;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;AbstractKeyValue;true;setValue;;;MapValue of Argument[-1];ReturnValue;value",
"org.apache.commons.collections4.keyvalue;AbstractKeyValue;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;AbstractKeyValue;true;toString;;;MapKey of Argument[-1];ReturnValue;taint",
"org.apache.commons.collections4.keyvalue;AbstractKeyValue;true;toString;;;MapValue of Argument[-1];ReturnValue;taint",
"org.apache.commons.collections4.keyvalue;AbstractMapEntry;true;AbstractMapEntry;;;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;AbstractMapEntry;true;AbstractMapEntry;;;Argument[1];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;AbstractMapEntryDecorator;true;AbstractMapEntryDecorator;;;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;AbstractMapEntryDecorator;true;AbstractMapEntryDecorator;;;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;AbstractMapEntryDecorator;true;getMapEntry;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"org.apache.commons.collections4.keyvalue;AbstractMapEntryDecorator;true;getMapEntry;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.apache.commons.collections4.keyvalue;AbstractMapEntryDecorator;true;toString;;;MapKey of Argument[-1];ReturnValue;taint",
"org.apache.commons.collections4.keyvalue;AbstractMapEntryDecorator;true;toString;;;MapValue of Argument[-1];ReturnValue;taint",
"org.apache.commons.collections4.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Object,Object);;Argument[1];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(KeyValue);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(KeyValue);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Entry);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Entry);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultKeyValue;true;toMapEntry;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"org.apache.commons.collections4.keyvalue;DefaultKeyValue;true;toMapEntry;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.apache.commons.collections4.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Object,Object);;Argument[1];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(KeyValue);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(KeyValue);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Entry);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Entry);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;TiedMapEntry;true;TiedMapEntry;;;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;TiedMapEntry;true;TiedMapEntry;;;Argument[1];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Object,Object);;Argument[1];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(KeyValue);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(KeyValue);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Entry);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections4.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Entry);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;AbstractKeyValue;true;AbstractKeyValue;;;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;AbstractKeyValue;true;AbstractKeyValue;;;Argument[1];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;AbstractKeyValue;true;setKey;;;MapValue of Argument[-1];ReturnValue;value",
"org.apache.commons.collections.keyvalue;AbstractKeyValue;true;setKey;;;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;AbstractKeyValue;true;setValue;;;MapValue of Argument[-1];ReturnValue;value",
"org.apache.commons.collections.keyvalue;AbstractKeyValue;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;AbstractKeyValue;true;toString;;;MapKey of Argument[-1];ReturnValue;taint",
"org.apache.commons.collections.keyvalue;AbstractKeyValue;true;toString;;;MapValue of Argument[-1];ReturnValue;taint",
"org.apache.commons.collections.keyvalue;AbstractMapEntry;true;AbstractMapEntry;;;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;AbstractMapEntry;true;AbstractMapEntry;;;Argument[1];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;AbstractMapEntryDecorator;true;AbstractMapEntryDecorator;;;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;AbstractMapEntryDecorator;true;AbstractMapEntryDecorator;;;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;AbstractMapEntryDecorator;true;getMapEntry;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"org.apache.commons.collections.keyvalue;AbstractMapEntryDecorator;true;getMapEntry;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.apache.commons.collections.keyvalue;AbstractMapEntryDecorator;true;toString;;;MapKey of Argument[-1];ReturnValue;taint",
"org.apache.commons.collections.keyvalue;AbstractMapEntryDecorator;true;toString;;;MapValue of Argument[-1];ReturnValue;taint",
"org.apache.commons.collections.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Object,Object);;Argument[1];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(KeyValue);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(KeyValue);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Entry);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultKeyValue;true;DefaultKeyValue;(Entry);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultKeyValue;true;toMapEntry;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"org.apache.commons.collections.keyvalue;DefaultKeyValue;true;toMapEntry;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.apache.commons.collections.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Object,Object);;Argument[1];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(KeyValue);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(KeyValue);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Entry);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Entry);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;TiedMapEntry;true;TiedMapEntry;;;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;TiedMapEntry;true;TiedMapEntry;;;Argument[1];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Object,Object);;Argument[1];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(KeyValue);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(KeyValue);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.apache.commons.collections.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Entry);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.apache.commons.collections.keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Entry);;MapValue of Argument[0];MapValue of Argument[-1];value"
]
}
}
/**
* Value-propagating models for the class `org.apache.commons.collections4.MapUtils`.
*/
private class ApacheMapUtilsModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.collections4;MapUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;fixedSizeMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;fixedSizeMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;fixedSizeSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;fixedSizeSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;getMap;;;MapValue of Argument[0];ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;getMap;;;Argument[2];ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;getObject;;;MapValue of Argument[0];ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;getObject;;;Argument[2];ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;getString;;;MapValue of Argument[0];ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;getString;;;Argument[2];ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;invertMap;;;MapKey of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;invertMap;;;MapValue of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;iterableMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;iterableMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;iterableSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;iterableSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;lazyMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;lazyMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;lazySortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;lazySortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;multiValueMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;multiValueMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;orderedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;orderedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;populateMap;(Map,Iterable,Transformer);;Element of Argument[1];MapValue of Argument[0];value",
"org.apache.commons.collections4;MapUtils;true;populateMap;(MultiMap,Iterable,Transformer);;Element of Argument[1];MapValue of Argument[0];value",
// Note that when lambdas are supported we should have more models for populateMap
"org.apache.commons.collections4;MapUtils;true;predicatedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;predicatedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;predicatedSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;predicatedSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;ArrayElement of Argument[1];MapKey of Argument[0];value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;ArrayElement of Argument[1];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;ArrayElement of Argument[1];MapValue of Argument[0];value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;ArrayElement of Argument[1];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;ArrayElement of ArrayElement of Argument[1];MapKey of Argument[0];value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;ArrayElement of ArrayElement of Argument[1];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;ArrayElement of ArrayElement of Argument[1];MapValue of Argument[0];value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;ArrayElement of ArrayElement of Argument[1];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;MapKey of ArrayElement of Argument[1];MapKey of Argument[0];value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;MapKey of ArrayElement of Argument[1];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;MapValue of ArrayElement of Argument[1];MapValue of Argument[0];value",
"org.apache.commons.collections4;MapUtils;true;putAll;;;MapValue of ArrayElement of Argument[1];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;safeAddToMap;;;Argument[1];MapKey of Argument[0];value",
"org.apache.commons.collections4;MapUtils;true;safeAddToMap;;;Argument[2];MapValue of Argument[0];value",
"org.apache.commons.collections4;MapUtils;true;synchronizedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;synchronizedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;synchronizedSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;synchronizedSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;toMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;toMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;transformedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;transformedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;transformedSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;transformedSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;unmodifiableMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;unmodifiableMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;unmodifiableSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections4;MapUtils;true;unmodifiableSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;emptyIfNull;;;Argument[0];ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;fixedSizeMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;fixedSizeMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;fixedSizeSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;fixedSizeSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;getMap;;;MapValue of Argument[0];ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;getMap;;;Argument[2];ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;getObject;;;MapValue of Argument[0];ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;getObject;;;Argument[2];ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;getString;;;MapValue of Argument[0];ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;getString;;;Argument[2];ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;invertMap;;;MapKey of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;invertMap;;;MapValue of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;iterableMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;iterableMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;iterableSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;iterableSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;lazyMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;lazyMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;lazySortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;lazySortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;multiValueMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;multiValueMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;orderedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;orderedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;populateMap;(Map,Iterable,Transformer);;Element of Argument[1];MapValue of Argument[0];value",
"org.apache.commons.collections;MapUtils;true;populateMap;(MultiMap,Iterable,Transformer);;Element of Argument[1];MapValue of Argument[0];value",
// Note that when lambdas are supported we should have more models for populateMap
"org.apache.commons.collections;MapUtils;true;predicatedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;predicatedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;predicatedSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;predicatedSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;putAll;;;ArrayElement of Argument[1];MapKey of Argument[0];value",
"org.apache.commons.collections;MapUtils;true;putAll;;;ArrayElement of Argument[1];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;putAll;;;ArrayElement of Argument[1];MapValue of Argument[0];value",
"org.apache.commons.collections;MapUtils;true;putAll;;;ArrayElement of Argument[1];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;putAll;;;ArrayElement of ArrayElement of Argument[1];MapKey of Argument[0];value",
"org.apache.commons.collections;MapUtils;true;putAll;;;ArrayElement of ArrayElement of Argument[1];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;putAll;;;ArrayElement of ArrayElement of Argument[1];MapValue of Argument[0];value",
"org.apache.commons.collections;MapUtils;true;putAll;;;ArrayElement of ArrayElement of Argument[1];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;putAll;;;MapKey of ArrayElement of Argument[1];MapKey of Argument[0];value",
"org.apache.commons.collections;MapUtils;true;putAll;;;MapKey of ArrayElement of Argument[1];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;putAll;;;MapValue of ArrayElement of Argument[1];MapValue of Argument[0];value",
"org.apache.commons.collections;MapUtils;true;putAll;;;MapValue of ArrayElement of Argument[1];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;safeAddToMap;;;Argument[1];MapKey of Argument[0];value",
"org.apache.commons.collections;MapUtils;true;safeAddToMap;;;Argument[2];MapValue of Argument[0];value",
"org.apache.commons.collections;MapUtils;true;synchronizedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;synchronizedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;synchronizedSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;synchronizedSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;toMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;toMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;transformedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;transformedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;transformedSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;transformedSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;unmodifiableMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;unmodifiableMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;unmodifiableSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.collections;MapUtils;true;unmodifiableSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value"
]
}
}

View File

@@ -34,38 +34,41 @@ private class ApacheArrayUtilsModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.lang3;ArrayUtils;false;add;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;add;;;Argument[2];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;add;(java.lang.Object[],java.lang.Object);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;add;(boolean[],boolean);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;add;(byte[],byte);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;add;(char[],char);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;add;(double[],double);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;add;(float[],float);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;add;(int[],int);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;add;(long[],long);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;add;(short[],short);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;addAll;;;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;addFirst;;;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;clone;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;get;(java.lang.Object[],int,java.lang.Object);;Argument[2];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;get;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;insert;;;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;insert;;;Argument[2];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;insert;;;Argument[3];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;nullToEmpty;(java.lang.Object[],java.lang.Class);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;nullToEmpty;(java.lang.String[]);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;remove;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;removeAll;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;removeAllOccurences;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;removeAllOccurrences;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;removeElement;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;removeElements;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;subarray;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;toArray;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;toMap;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;toObject;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;ArrayUtils;false;toPrimitive;;;Argument[0..1];ReturnValue;taint"
"org.apache.commons.lang3;ArrayUtils;false;add;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;add;;;Argument[2];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;add;(java.lang.Object[],java.lang.Object);;Argument[1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;add;(boolean[],boolean);;Argument[1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;add;(byte[],byte);;Argument[1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;add;(char[],char);;Argument[1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;add;(double[],double);;Argument[1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;add;(float[],float);;Argument[1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;add;(int[],int);;Argument[1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;add;(long[],long);;Argument[1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;add;(short[],short);;Argument[1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;addAll;;;ArrayElement of Argument[0..1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;addFirst;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;addFirst;;;Argument[1];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;clone;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;get;(java.lang.Object[],int,java.lang.Object);;Argument[2];ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;get;;;ArrayElement of Argument[0];ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;insert;;;ArrayElement of Argument[1..2];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;nullToEmpty;(java.lang.Object[],java.lang.Class);;Argument[0];ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;nullToEmpty;(java.lang.String[]);;Argument[0];ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;remove;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;removeAll;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;removeAllOccurences;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;removeAllOccurrences;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;removeElement;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;removeElements;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;subarray;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;toArray;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;toMap;;;MapKey of ArrayElement of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;toMap;;;MapValue of ArrayElement of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;toMap;;;ArrayElement of ArrayElement of Argument[0];MapKey of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;toMap;;;ArrayElement of ArrayElement of Argument[0];MapValue of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;toObject;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;toPrimitive;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.apache.commons.lang3;ArrayUtils;false;toPrimitive;;;Argument[1];ArrayElement of ReturnValue;value"
]
}
}
@@ -789,3 +792,86 @@ private class ApacheToStringBuilderModel extends SummaryModelCsv {
]
}
}
/**
* Value-propagating models for `Pair`, `ImmutablePair` and `MutablePair`.
*/
private class ApachePairModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.lang3.tuple;Pair;false;getKey;;;Field[org.apache.commons.lang3.tuple.ImmutablePair.left] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;Pair;false;getValue;;;Field[org.apache.commons.lang3.tuple.ImmutablePair.right] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;Pair;false;getKey;;;Field[org.apache.commons.lang3.tuple.MutablePair.left] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;Pair;false;getValue;;;Field[org.apache.commons.lang3.tuple.MutablePair.right] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;Pair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];Field[org.apache.commons.lang3.tuple.ImmutablePair.left] of ReturnValue;value",
"org.apache.commons.lang3.tuple;Pair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];Field[org.apache.commons.lang3.tuple.ImmutablePair.right] of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;ImmutablePair;(java.lang.Object,java.lang.Object);;Argument[0];Field[org.apache.commons.lang3.tuple.ImmutablePair.left] of Argument[-1];value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;ImmutablePair;(java.lang.Object,java.lang.Object);;Argument[1];Field[org.apache.commons.lang3.tuple.ImmutablePair.right] of Argument[-1];value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;getLeft;;;Field[org.apache.commons.lang3.tuple.ImmutablePair.left] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;getRight;;;Field[org.apache.commons.lang3.tuple.ImmutablePair.right] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;left;;;Argument[0];Field[org.apache.commons.lang3.tuple.ImmutablePair.left] of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;right;;;Argument[0];Field[org.apache.commons.lang3.tuple.ImmutablePair.right] of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];Field[org.apache.commons.lang3.tuple.ImmutablePair.left] of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];Field[org.apache.commons.lang3.tuple.ImmutablePair.right] of ReturnValue;value",
"org.apache.commons.lang3.tuple;MutablePair;false;MutablePair;(java.lang.Object,java.lang.Object);;Argument[0];Field[org.apache.commons.lang3.tuple.MutablePair.left] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutablePair;false;MutablePair;(java.lang.Object,java.lang.Object);;Argument[1];Field[org.apache.commons.lang3.tuple.MutablePair.right] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutablePair;false;getLeft;;;Field[org.apache.commons.lang3.tuple.MutablePair.left] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;MutablePair;false;getRight;;;Field[org.apache.commons.lang3.tuple.MutablePair.right] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;MutablePair;false;setLeft;;;Argument[0];Field[org.apache.commons.lang3.tuple.MutablePair.left] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutablePair;false;setRight;;;Argument[0];Field[org.apache.commons.lang3.tuple.MutablePair.right] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutablePair;false;setValue;;;Argument[0];Field[org.apache.commons.lang3.tuple.MutablePair.right] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[0];Field[org.apache.commons.lang3.tuple.MutablePair.left] of ReturnValue;value",
"org.apache.commons.lang3.tuple;MutablePair;false;of;(java.lang.Object,java.lang.Object);;Argument[1];Field[org.apache.commons.lang3.tuple.MutablePair.right] of ReturnValue;value"
]
}
}
/**
* Value-propagating models for `Triple`, `ImmutableTriple` and `MutableTriple`.
*/
private class ApacheTripleModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Field[org.apache.commons.lang3.tuple.ImmutableTriple.left] of ReturnValue;value",
"org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle] of ReturnValue;value",
"org.apache.commons.lang3.tuple;Triple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Field[org.apache.commons.lang3.tuple.ImmutableTriple.right] of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;ImmutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Field[org.apache.commons.lang3.tuple.ImmutableTriple.left] of Argument[-1];value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;ImmutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle] of Argument[-1];value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;ImmutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Field[org.apache.commons.lang3.tuple.ImmutableTriple.right] of Argument[-1];value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;getLeft;;;Field[org.apache.commons.lang3.tuple.ImmutableTriple.left] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;getMiddle;;;Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;getRight;;;Field[org.apache.commons.lang3.tuple.ImmutableTriple.right] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Field[org.apache.commons.lang3.tuple.ImmutableTriple.left] of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Field[org.apache.commons.lang3.tuple.ImmutableTriple.middle] of ReturnValue;value",
"org.apache.commons.lang3.tuple;ImmutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Field[org.apache.commons.lang3.tuple.ImmutableTriple.right] of ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;MutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Field[org.apache.commons.lang3.tuple.MutableTriple.left] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutableTriple;false;MutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Field[org.apache.commons.lang3.tuple.MutableTriple.middle] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutableTriple;false;MutableTriple;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Field[org.apache.commons.lang3.tuple.MutableTriple.right] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutableTriple;false;getLeft;;;Field[org.apache.commons.lang3.tuple.MutableTriple.left] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;getMiddle;;;Field[org.apache.commons.lang3.tuple.MutableTriple.middle] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;getRight;;;Field[org.apache.commons.lang3.tuple.MutableTriple.right] of Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;setLeft;;;Argument[0];Field[org.apache.commons.lang3.tuple.MutableTriple.left] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutableTriple;false;setMiddle;;;Argument[0];Field[org.apache.commons.lang3.tuple.MutableTriple.middle] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutableTriple;false;setRight;;;Argument[0];Field[org.apache.commons.lang3.tuple.MutableTriple.right] of Argument[-1];value",
"org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[0];Field[org.apache.commons.lang3.tuple.MutableTriple.left] of ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[1];Field[org.apache.commons.lang3.tuple.MutableTriple.middle] of ReturnValue;value",
"org.apache.commons.lang3.tuple;MutableTriple;false;of;(java.lang.Object,java.lang.Object,java.lang.Object);;Argument[2];Field[org.apache.commons.lang3.tuple.MutableTriple.right] of ReturnValue;value"
]
}
}
/**
* Value-propagating models for `MutableObject`.
*/
private class ApacheMutableObjectModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.lang3.mutable;MutableObject;false;MutableObject;;;Argument[0];SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value] of Argument[-1];value",
"org.apache.commons.lang3.mutable;MutableObject;false;setValue;;;Argument[0];SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value] of Argument[-1];value",
"org.apache.commons.lang3.mutable;MutableObject;false;getValue;;;SyntheticField[org.apache.commons.lang3.mutable.MutableObject.value] of Argument[-1];ReturnValue;value"
]
}
}

View File

@@ -7,7 +7,7 @@ private class GuavaBaseCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;inputspec;outputspec;kind",
//`namespace; type; subtypes; name; signature; ext; input; output; kind`
"com.google.common.base;Strings;false;emptyToNull;(String);;Argument[0];ReturnValue;value",
"com.google.common.base;Strings;false;nullToEmpty;(String);;Argument[0];ReturnValue;value",
"com.google.common.base;Strings;false;padStart;(String,int,char);;Argument[0];ReturnValue;taint",

View File

@@ -7,7 +7,7 @@ private class GuavaIoCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;inputspec;outputspec;kind",
//`namespace; type; subtypes; name; signature; ext; input; output; kind`
"com.google.common.io;BaseEncoding;true;decode;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;decodingStream;(Reader);;Argument[0];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;decodingSource;(CharSource);;Argument[0];ReturnValue;taint",
@@ -89,7 +89,7 @@ private class GuavaIoSinkCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;inputspec;kind",
//`namespace; type; subtypes; name; signature; ext; input; kind`
"com.google.common.io;Resources;false;asByteSource;(URL);;Argument[0];url-open-stream",
"com.google.common.io;Resources;false;asCharSource;(URL,Charset);;Argument[0];url-open-stream",
"com.google.common.io;Resources;false;copy;(URL,OutputStream);;Argument[0];url-open-stream",

View File

@@ -3,6 +3,7 @@
*/
import java
import semmle.code.java.dataflow.ExternalFlow
/**
* Methods annotated with this allow for generation of "plain SQL"
@@ -21,3 +22,13 @@ predicate jOOQSqlMethod(Method m) {
m.getAnAnnotation() instanceof PlainSQLType and
m.getParameterType(0) instanceof TypeString
}
private class SqlSinkCsv extends SinkModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;spec;kind"
"org.jooq;PlainSQL;false;;;Annotated;Argument[0];sql"
]
}
}

View File

@@ -26,10 +26,10 @@ class PlayMvcHttpRequestHeader extends RefType {
}
/**
* A `play.mvc.BodyParser<>$Of` annotation.
* A `play.mvc.BodyParser$Of` annotation.
*/
class PlayBodyParserAnnotation extends Annotation {
PlayBodyParserAnnotation() { this.getType().hasQualifiedName("play.mvc", "BodyParser<>$Of") }
PlayBodyParserAnnotation() { this.getType().hasQualifiedName("play.mvc", "BodyParser$Of") }
}
/**

View File

@@ -6,7 +6,9 @@ import semmle.code.java.frameworks.spring.SpringAttribute
import semmle.code.java.frameworks.spring.SpringAutowire
import semmle.code.java.frameworks.spring.SpringBean
import semmle.code.java.frameworks.spring.SpringBeanFile
import semmle.code.java.frameworks.spring.SpringBeans
import semmle.code.java.frameworks.spring.SpringBeanRefType
import semmle.code.java.frameworks.spring.SpringCache
import semmle.code.java.frameworks.spring.SpringComponentScan
import semmle.code.java.frameworks.spring.SpringConstructorArg
import semmle.code.java.frameworks.spring.SpringController
@@ -32,7 +34,11 @@ import semmle.code.java.frameworks.spring.SpringQualifier
import semmle.code.java.frameworks.spring.SpringRef
import semmle.code.java.frameworks.spring.SpringReplacedMethod
import semmle.code.java.frameworks.spring.SpringSet
import semmle.code.java.frameworks.spring.SpringUi
import semmle.code.java.frameworks.spring.SpringUtil
import semmle.code.java.frameworks.spring.SpringValidation
import semmle.code.java.frameworks.spring.SpringValue
import semmle.code.java.frameworks.spring.SpringWebMultipart
import semmle.code.java.frameworks.spring.SpringXMLElement
import semmle.code.java.frameworks.spring.metrics.MetricSpringBean
import semmle.code.java.frameworks.spring.metrics.MetricSpringBeanFile

View File

@@ -0,0 +1,44 @@
/**
* Provides classes and predicates for working with Spring classes and interfaces from
* `org.springframework.beans`.
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
/**
* Provides models for the `org.springframework.beans` package.
*/
private class FlowSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.springframework.beans;PropertyValue;false;PropertyValue;(String,Object);;Argument[0];MapKey of Argument[-1];value",
"org.springframework.beans;PropertyValue;false;PropertyValue;(String,Object);;Argument[1];MapValue of Argument[-1];value",
"org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue);;Argument[0];Argument[-1];value",
"org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue,Object);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.springframework.beans;PropertyValue;false;PropertyValue;(PropertyValue,Object);;Argument[1];MapValue of Argument[-1];value",
"org.springframework.beans;PropertyValue;false;getName;;;MapKey of Argument[-1];ReturnValue;value",
"org.springframework.beans;PropertyValue;false;getValue;;;MapValue of Argument[-1];ReturnValue;value",
"org.springframework.beans;PropertyValues;true;getPropertyValue;;;Element of Argument[-1];ReturnValue;value",
"org.springframework.beans;PropertyValues;true;getPropertyValues;;;Element of Argument[-1];ArrayElement of ReturnValue;value",
"org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[0];MapKey of Element of Argument[-1];value",
"org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[-1];ReturnValue;value",
"org.springframework.beans;MutablePropertyValues;true;add;(String,Object);;Argument[1];MapValue of Element of Argument[-1];value",
"org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(PropertyValue);;Argument[0];Element of Argument[-1];value",
"org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(PropertyValue);;Argument[-1];ReturnValue;value",
"org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(String,Object);;Argument[0];MapKey of Element of Argument[-1];value",
"org.springframework.beans;MutablePropertyValues;true;addPropertyValue;(String,Object);;Argument[1];MapValue of Element of Argument[-1];value",
"org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;MapKey of Argument[0];MapKey of Element of Argument[-1];value",
"org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;MapValue of Argument[0];MapValue of Element of Argument[-1];value",
"org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(Map);;Argument[-1];ReturnValue;value",
"org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(PropertyValues);;Element of Argument[0];Element of Argument[-1];value",
"org.springframework.beans;MutablePropertyValues;true;addPropertyValues;(PropertyValues);;Argument[-1];ReturnValue;value",
"org.springframework.beans;MutablePropertyValues;true;get;;;MapValue of Element of Argument[-1];ReturnValue;value",
"org.springframework.beans;MutablePropertyValues;true;getPropertyValue;;;Element of Argument[-1];ReturnValue;value",
"org.springframework.beans;MutablePropertyValues;true;getPropertyValueList;;;Element of Argument[-1];Element of ReturnValue;value",
"org.springframework.beans;MutablePropertyValues;true;getPropertyValues;;;Element of Argument[-1];ArrayElement of ReturnValue;value",
"org.springframework.beans;MutablePropertyValues;true;setPropertyValueAt;;;Argument[0];Element of Argument[-1];value"
]
}
}

View File

@@ -0,0 +1,27 @@
/**
* Provides models for the `org.springframework.cache` package.
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
private class FlowSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.springframework.cache;Cache$ValueRetrievalException;false;ValueRetrievalException;;;Argument[0];MapKey of Argument[-1];value",
"org.springframework.cache;Cache$ValueRetrievalException;false;getKey;;;MapKey of Argument[-1];ReturnValue;value",
"org.springframework.cache;Cache$ValueWrapper;true;get;;;MapValue of Argument[-1];ReturnValue;value",
"org.springframework.cache;Cache;true;get;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.springframework.cache;Cache;true;get;(Object,Callable);;MapValue of Argument[-1];ReturnValue;value",
"org.springframework.cache;Cache;true;get;(Object,Class);;MapValue of Argument[-1];ReturnValue;value",
"org.springframework.cache;Cache;true;getNativeCache;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"org.springframework.cache;Cache;true;getNativeCache;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.springframework.cache;Cache;true;put;;;Argument[0];MapKey of Argument[-1];value",
"org.springframework.cache;Cache;true;put;;;Argument[1];MapValue of Argument[-1];value",
"org.springframework.cache;Cache;true;putIfAbsent;;;Argument[0];MapKey of Argument[-1];value",
"org.springframework.cache;Cache;true;putIfAbsent;;;Argument[1];MapValue of Argument[-1];value",
"org.springframework.cache;Cache;true;putIfAbsent;;;MapValue of Argument[-1];MapValue of ReturnValue;value"
]
}
}

View File

@@ -4,6 +4,7 @@
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
/** The class `org.springframework.http.HttpEntity` or an instantiation of it. */
class SpringHttpEntity extends Class {
@@ -38,3 +39,104 @@ class SpringResponseEntityBodyBuilder extends Interface {
class SpringHttpHeaders extends Class {
SpringHttpHeaders() { this.hasQualifiedName("org.springframework.http", "HttpHeaders") }
}
private class UrlOpenSink extends SinkModelCsv {
override predicate row(string row) {
row =
[
"org.springframework.http;RequestEntity;false;get;;;Argument[0];open-url",
"org.springframework.http;RequestEntity;false;post;;;Argument[0];open-url",
"org.springframework.http;RequestEntity;false;head;;;Argument[0];open-url",
"org.springframework.http;RequestEntity;false;delete;;;Argument[0];open-url",
"org.springframework.http;RequestEntity;false;options;;;Argument[0];open-url",
"org.springframework.http;RequestEntity;false;patch;;;Argument[0];open-url",
"org.springframework.http;RequestEntity;false;put;;;Argument[0];open-url",
"org.springframework.http;RequestEntity;false;method;;;Argument[1];open-url",
"org.springframework.http;RequestEntity;false;RequestEntity;(HttpMethod,URI);;Argument[1];open-url",
"org.springframework.http;RequestEntity;false;RequestEntity;(MultiValueMap,HttpMethod,URI);;Argument[2];open-url",
"org.springframework.http;RequestEntity;false;RequestEntity;(Object,HttpMethod,URI);;Argument[2];open-url",
"org.springframework.http;RequestEntity;false;RequestEntity;(Object,HttpMethod,URI,Type);;Argument[2];open-url",
"org.springframework.http;RequestEntity;false;RequestEntity;(Object,MultiValueMap,HttpMethod,URI);;Argument[3];open-url",
"org.springframework.http;RequestEntity;false;RequestEntity;(Object,MultiValueMap,HttpMethod,URI,Type);;Argument[3];open-url"
]
}
}
private class SpringHttpFlowStep extends SummaryModelCsv {
override predicate row(string row) {
row =
[
//"package;type;overrides;name;signature;ext;inputspec;outputspec;kind",
"org.springframework.http;HttpEntity;true;HttpEntity;(Object);;Argument[0];Argument[-1];taint",
"org.springframework.http;HttpEntity;true;HttpEntity;(Object,MultiValueMap);;Argument[0];Argument[-1];taint",
"org.springframework.http;HttpEntity;true;HttpEntity;(Object,MultiValueMap);;MapKey of Argument[1];Argument[-1];taint",
"org.springframework.http;HttpEntity;true;HttpEntity;(Object,MultiValueMap);;Element of MapValue of Argument[1];Argument[-1];taint",
"org.springframework.http;HttpEntity;true;HttpEntity;(MultiValueMap);;MapKey of Argument[0];Argument[-1];taint",
"org.springframework.http;HttpEntity;true;HttpEntity;(MultiValueMap);;Element of MapValue of Argument[0];Argument[-1];taint",
"org.springframework.http;HttpEntity;true;getBody;;;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpEntity;true;getHeaders;;;Argument[-1];ReturnValue;taint",
"org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,HttpStatus);;Argument[0];Argument[-1];taint",
"org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,HttpStatus);;Argument[0];Argument[-1];taint",
"org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,HttpStatus);;MapKey of Argument[1];Argument[-1];taint",
"org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,HttpStatus);;Element of MapValue of Argument[1];Argument[-1];taint",
"org.springframework.http;ResponseEntity;true;ResponseEntity;(MultiValueMap,HttpStatus);;MapKey of Argument[0];Argument[-1];taint",
"org.springframework.http;ResponseEntity;true;ResponseEntity;(MultiValueMap,HttpStatus);;Element of MapValue of Argument[0];Argument[-1];taint",
"org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,int);;Argument[0];Argument[-1];taint",
"org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,int);;MapKey of Argument[1];Argument[-1];taint",
"org.springframework.http;ResponseEntity;true;ResponseEntity;(Object,MultiValueMap,int);;Element of MapValue of Argument[1];Argument[-1];taint",
"org.springframework.http;ResponseEntity;true;of;(Optional);;Element of Argument[0];ReturnValue;taint",
"org.springframework.http;ResponseEntity;true;ok;(Object);;Argument[0];ReturnValue;taint",
"org.springframework.http;ResponseEntity;true;created;(URI);;Argument[0];ReturnValue;taint",
"org.springframework.http;ResponseEntity$BodyBuilder;true;contentLength;(long);;Argument[-1];ReturnValue;value",
"org.springframework.http;ResponseEntity$BodyBuilder;true;contentType;(MediaType);;Argument[-1];ReturnValue;value",
"org.springframework.http;ResponseEntity$BodyBuilder;true;body;(Object);;Argument[-1..0];ReturnValue;taint",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;allow;(HttpMethod[]);;Argument[-1];ReturnValue;value",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;eTag;(String);;Argument[-1];ReturnValue;value",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;eTag;(String);;Argument[0];Argument[-1];taint",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;header;(String,String[]);;Argument[-1];ReturnValue;value",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;header;(String,String[]);;Argument[0];Argument[-1];taint",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;header;(String,String[]);;ArrayElement of Argument[1];Argument[-1];taint",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;headers;(Consumer);;Argument[-1];ReturnValue;value",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;headers;(HttpHeaders);;Argument[-1];ReturnValue;value",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;headers;(HttpHeaders);;Argument[0];Argument[-1];taint",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;lastModified;;;Argument[-1];ReturnValue;value",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;location;(URI);;Argument[-1];ReturnValue;value",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;location;(URI);;Argument[0];Argument[-1];taint",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;varyBy;(String[]);;Argument[-1];ReturnValue;value",
"org.springframework.http;ResponseEntity$HeadersBuilder;true;build;();;Argument[-1];ReturnValue;taint",
"org.springframework.http;RequestEntity;true;getUrl;();;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;HttpHeaders;(MultiValueMap);;MapKey of Argument[0];Argument[-1];taint",
"org.springframework.http;HttpHeaders;true;HttpHeaders;(MultiValueMap);;Element of MapValue of Argument[0];Argument[-1];taint",
"org.springframework.http;HttpHeaders;true;get;(Object);;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getAccessControlAllowHeaders;();;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getAccessControlAllowOrigin;();;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getAccessControlExposeHeaders;();;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getAccessControlRequestHeaders;();;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getCacheControl;();;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getConnection;();;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getETag;();;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getETagValuesAsList;(String);;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getFieldValues;(String);;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getFirst;(String);;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getIfMatch;();;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getIfNoneMatch;();;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getHost;();;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getLocation;();;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getOrEmpty;(Object);;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getOrigin;();;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getPragma;();;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getUpgrade;();;Argument[-1];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getValuesAsList;(String);;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;getVary;();;Argument[-1];Element of ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;add;(String,String);;Argument[0..1];Argument[-1];taint",
"org.springframework.http;HttpHeaders;true;set;(String,String);;Argument[0..1];Argument[-1];taint",
"org.springframework.http;HttpHeaders;true;addAll;(MultiValueMap);;MapKey of Argument[0];Argument[-1];taint",
"org.springframework.http;HttpHeaders;true;addAll;(MultiValueMap);;Element of MapValue of Argument[0];Argument[-1];taint",
"org.springframework.http;HttpHeaders;true;addAll;(String,List);;Argument[0];Argument[-1];taint",
"org.springframework.http;HttpHeaders;true;addAll;(String,List);;Element of Argument[1];Argument[-1];taint",
"org.springframework.http;HttpHeaders;true;formatHeaders;(MultiValueMap);;MapKey of Argument[0];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;formatHeaders;(MultiValueMap);;Element of MapValue of Argument[0];ReturnValue;taint",
"org.springframework.http;HttpHeaders;true;encodeBasicAuth;(String,String,Charset);;Argument[0..1];ReturnValue;taint"
]
}
}

View File

@@ -0,0 +1,46 @@
/**
* Provides models for the `org.springframework.ui` package.
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
private class FlowSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.springframework.ui;Model;true;addAllAttributes;;;Argument[-1];ReturnValue;value",
"org.springframework.ui;Model;true;addAllAttributes;(Collection);;Element of Argument[0];MapValue of Argument[-1];value",
"org.springframework.ui;Model;true;addAllAttributes;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.springframework.ui;Model;true;addAllAttributes;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.springframework.ui;Model;true;addAttribute;;;Argument[-1];ReturnValue;value",
"org.springframework.ui;Model;true;addAttribute;(Object);;Argument[0];MapValue of Argument[-1];value",
"org.springframework.ui;Model;true;addAttribute;(String,Object);;Argument[0];MapKey of Argument[-1];value",
"org.springframework.ui;Model;true;addAttribute;(String,Object);;Argument[1];MapValue of Argument[-1];value",
"org.springframework.ui;Model;true;asMap;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"org.springframework.ui;Model;true;asMap;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.springframework.ui;Model;true;getAttribute;;;MapValue of Argument[-1];ReturnValue;value",
"org.springframework.ui;Model;true;mergeAttributes;;;Argument[-1];ReturnValue;value",
"org.springframework.ui;Model;true;mergeAttributes;;;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.springframework.ui;Model;true;mergeAttributes;;;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.springframework.ui;ModelMap;false;ModelMap;(Object);;Argument[0];MapValue of Argument[-1];value",
"org.springframework.ui;ModelMap;false;ModelMap;(String,Object);;Argument[0];MapKey of Argument[-1];value",
"org.springframework.ui;ModelMap;false;ModelMap;(String,Object);;Argument[1];MapValue of Argument[-1];value",
"org.springframework.ui;ModelMap;false;addAllAttributes;;;Argument[-1];ReturnValue;value",
"org.springframework.ui;ModelMap;false;addAllAttributes;(Collection);;Element of Argument[0];MapValue of Argument[-1];value",
"org.springframework.ui;ModelMap;false;addAllAttributes;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.springframework.ui;ModelMap;false;addAllAttributes;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.springframework.ui;ModelMap;false;addAttribute;;;Argument[-1];ReturnValue;value",
"org.springframework.ui;ModelMap;false;addAttribute;(Object);;Argument[0];MapValue of Argument[-1];value",
"org.springframework.ui;ModelMap;false;addAttribute;(String,Object);;Argument[0];MapKey of Argument[-1];value",
"org.springframework.ui;ModelMap;false;addAttribute;(String,Object);;Argument[1];MapValue of Argument[-1];value",
"org.springframework.ui;ModelMap;false;getAttribute;;;MapValue of Argument[-1];ReturnValue;value",
"org.springframework.ui;ModelMap;false;mergeAttributes;;;Argument[-1];ReturnValue;value",
"org.springframework.ui;ModelMap;false;mergeAttributes;;;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.springframework.ui;ModelMap;false;mergeAttributes;;;MapValue of Argument[0];MapValue of Argument[-1];value",
"org.springframework.ui;ConcurrentModel;false;ConcurrentModel;(Object);;Argument[0];MapValue of Argument[-1];value",
"org.springframework.ui;ConcurrentModel;false;ConcurrentModel;(String,Object);;Argument[0];MapKey of Argument[-1];value",
"org.springframework.ui;ConcurrentModel;false;ConcurrentModel;(String,Object);;Argument[1];MapValue of Argument[-1];value"
]
}
}

View File

@@ -0,0 +1,153 @@
/**
* Provides models for the `org.springframework.util` package.
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
private class FlowSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.springframework.util;AntPathMatcher;false;combine;;;Argument[0..1];ReturnValue;taint",
"org.springframework.util;AntPathMatcher;false;doMatch;;;Argument[1];MapValue of Argument[3];taint",
"org.springframework.util;AntPathMatcher;false;extractPathWithinPattern;;;Argument[1];ReturnValue;taint",
"org.springframework.util;AntPathMatcher;false;extractUriTemplateVariables;;;Argument[1];MapValue of ReturnValue;taint",
"org.springframework.util;AntPathMatcher;false;tokenizePath;;;Argument[0];ArrayElement of ReturnValue;taint",
"org.springframework.util;AntPathMatcher;false;tokenizePattern;;;Argument[0];ArrayElement of ReturnValue;taint",
"org.springframework.util;AutoPopulatingList;false;AutoPopulatingList;(java.util.List,org.springframework.util.AutoPopulatingList.ElementFactory);;Element of Argument[0];Element of Argument[-1];value",
"org.springframework.util;AutoPopulatingList;false;AutoPopulatingList;(java.util.List,java.lang.Class);;Element of Argument[0];Element of Argument[-1];value",
"org.springframework.util;Base64Utils;false;decode;;;Argument[0];ReturnValue;taint",
"org.springframework.util;Base64Utils;false;decodeFromString;;;Argument[0];ReturnValue;taint",
"org.springframework.util;Base64Utils;false;decodeFromUrlSafeString;;;Argument[0];ReturnValue;taint",
"org.springframework.util;Base64Utils;false;decodeUrlSafe;;;Argument[0];ReturnValue;taint",
"org.springframework.util;Base64Utils;false;encode;;;Argument[0];ReturnValue;taint",
"org.springframework.util;Base64Utils;false;encodeToString;;;Argument[0];ReturnValue;taint",
"org.springframework.util;Base64Utils;false;encodeToUrlSafeString;;;Argument[0];ReturnValue;taint",
"org.springframework.util;Base64Utils;false;encodeUrlSafe;;;Argument[0];ReturnValue;taint",
"org.springframework.util;CollectionUtils;false;arrayToList;;;ArrayElement of Argument[0];Element of ReturnValue;value",
"org.springframework.util;CollectionUtils;false;findFirstMatch;;;Element of Argument[0];ReturnValue;value",
"org.springframework.util;CollectionUtils;false;findValueOfType;;;Element of Argument[0];ReturnValue;value",
"org.springframework.util;CollectionUtils;false;firstElement;;;Element of Argument[0];ReturnValue;value",
"org.springframework.util;CollectionUtils;false;lastElement;;;Element of Argument[0];ReturnValue;value",
"org.springframework.util;CollectionUtils;false;mergeArrayIntoCollection;;;ArrayElement of Argument[0];Element of Argument[1];value",
"org.springframework.util;CollectionUtils;false;mergePropertiesIntoMap;;;MapKey of Argument[0];MapKey of Argument[1];value",
"org.springframework.util;CollectionUtils;false;mergePropertiesIntoMap;;;MapValue of Argument[0];MapValue of Argument[1];value",
"org.springframework.util;CollectionUtils;false;toArray;;;Element of Argument[0];ArrayElement of ReturnValue;value",
"org.springframework.util;CollectionUtils;false;toIterator;;;Element of Argument[0];Element of ReturnValue;value",
"org.springframework.util;CollectionUtils;false;toMultiValueMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.springframework.util;CollectionUtils;false;toMultiValueMap;;;Element of MapValue of Argument[0];Element of MapValue of ReturnValue;value",
"org.springframework.util;CollectionUtils;false;unmodifiableMultiValueMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
"org.springframework.util;CollectionUtils;false;unmodifiableMultiValueMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
"org.springframework.util;CompositeIterator;false;add;;;Element of Argument[0];Element of Argument[-1];value",
"org.springframework.util;ConcurrentReferenceHashMap;false;getReference;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"org.springframework.util;ConcurrentReferenceHashMap;false;getReference;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.springframework.util;ConcurrentReferenceHashMap;false;getSegment;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"org.springframework.util;ConcurrentReferenceHashMap;false;getSegment;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.springframework.util;FastByteArrayOutputStream;false;getInputStream;;;Argument[-1];ReturnValue;taint",
"org.springframework.util;FastByteArrayOutputStream;false;toByteArray;;;Argument[-1];ReturnValue;taint",
"org.springframework.util;FastByteArrayOutputStream;false;write;;;Argument[0];Argument[-1];taint",
"org.springframework.util;FastByteArrayOutputStream;false;writeTo;;;Argument[-1];Argument[0];taint",
"org.springframework.util;FileCopyUtils;false;copy;;;Argument[0];Argument[1];taint",
"org.springframework.util;FileCopyUtils;false;copyToByteArray;;;Argument[0];ReturnValue;taint",
"org.springframework.util;FileCopyUtils;false;copyToString;;;Argument[0];ReturnValue;taint",
"org.springframework.util;FileSystemUtils;false;copyRecursively;(java.io.File,java.io.File);;Argument[0];Argument[1];taint",
"org.springframework.util;LinkedMultiValueMap;false;LinkedMultiValueMap;(java.util.Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.springframework.util;LinkedMultiValueMap;false;LinkedMultiValueMap;(java.util.Map);;Element of MapValue of Argument[0];Element of MapValue of Argument[-1];value",
"org.springframework.util;LinkedMultiValueMap;false;deepCopy;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"org.springframework.util;LinkedMultiValueMap;false;deepCopy;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.springframework.util;MultiValueMap;true;add;;;Argument[0];MapKey of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;add;;;Argument[1];Element of MapValue of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;addAll;(java.lang.Object,java.util.List);;Argument[0];MapKey of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;addAll;(java.lang.Object,java.util.List);;Element of Argument[1];Element of MapValue of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;addAll;(org.springframework.util.MultiValueMap);;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;addAll;(org.springframework.util.MultiValueMap);;Element of MapValue of Argument[0];Element of MapValue of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;addIfAbsent;;;Argument[0];MapKey of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;addIfAbsent;;;Argument[1];Element of MapValue of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;getFirst;;;Element of MapValue of Argument[-1];ReturnValue;value",
"org.springframework.util;MultiValueMap;true;set;;;Argument[0];MapKey of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;set;;;Argument[1];Element of MapValue of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;setAll;;;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;setAll;;;MapValue of Argument[0];Element of MapValue of Argument[-1];value",
"org.springframework.util;MultiValueMap;true;toSingleValueMap;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"org.springframework.util;MultiValueMap;true;toSingleValueMap;;;Element of MapValue of Argument[-1];MapValue of ReturnValue;value",
"org.springframework.util;MultiValueMapAdapter;false;MultiValueMapAdapter;;;MapKey of Argument[0];MapKey of Argument[-1];value",
"org.springframework.util;MultiValueMapAdapter;false;MultiValueMapAdapter;;;Element of MapValue of Argument[0];Element of MapValue of Argument[-1];value",
"org.springframework.util;ObjectUtils;false;addObjectToArray;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.springframework.util;ObjectUtils;false;addObjectToArray;;;Argument[1];ArrayElement of ReturnValue;value",
"org.springframework.util;ObjectUtils;false;toObjectArray;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.springframework.util;ObjectUtils;false;unwrapOptional;;;Element of Argument[0];ReturnValue;value",
"org.springframework.util;PropertiesPersister;true;load;;;Argument[1];Argument[0];taint",
"org.springframework.util;PropertiesPersister;true;loadFromXml;;;Argument[1];Argument[0];taint",
"org.springframework.util;PropertiesPersister;true;store;;;Argument[0];Argument[1];taint",
"org.springframework.util;PropertiesPersister;true;store;;;Argument[2];Argument[1];taint",
"org.springframework.util;PropertiesPersister;true;storeToXml;;;Argument[0];Argument[1];taint",
"org.springframework.util;PropertiesPersister;true;storeToXml;;;Argument[2];Argument[1];taint",
"org.springframework.util;PropertyPlaceholderHelper;false;PropertyPlaceholderHelper;;;Argument[0..1];Argument[-1];taint",
"org.springframework.util;PropertyPlaceholderHelper;false;parseStringValue;;;Argument[0];ReturnValue;taint",
"org.springframework.util;PropertyPlaceholderHelper;false;replacePlaceholders;;;Argument[0];ReturnValue;taint",
"org.springframework.util;PropertyPlaceholderHelper;false;replacePlaceholders;(java.lang.String,java.util.Properties);;MapValue of Argument[1];ReturnValue;taint",
"org.springframework.util;ResourceUtils;false;extractArchiveURL;;;Argument[0];ReturnValue;taint",
"org.springframework.util;ResourceUtils;false;extractJarFileURL;;;Argument[0];ReturnValue;taint",
"org.springframework.util;ResourceUtils;false;getFile;;;Argument[0];ReturnValue;taint",
"org.springframework.util;ResourceUtils;false;getURL;;;Argument[0];ReturnValue;taint",
"org.springframework.util;ResourceUtils;false;toURI;;;Argument[0];ReturnValue;taint",
"org.springframework.util;RouteMatcher;true;combine;;;Argument[0..1];ReturnValue;taint",
"org.springframework.util;RouteMatcher;true;matchAndExtract;;;Argument[0];MapKey of ReturnValue;taint",
"org.springframework.util;RouteMatcher;true;matchAndExtract;;;Argument[1];MapValue of ReturnValue;taint",
"org.springframework.util;RouteMatcher;true;parseRoute;;;Argument[0];ReturnValue;taint",
"org.springframework.util;SerializationUtils;false;deserialize;;;Argument[0];ReturnValue;taint",
"org.springframework.util;SerializationUtils;false;serialize;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StreamUtils;false;copy;(byte[],java.io.OutputStream);;Argument[0];Argument[1];taint",
"org.springframework.util;StreamUtils;false;copy;(java.io.InputStream,java.io.OutputStream);;Argument[0];Argument[1];taint",
"org.springframework.util;StreamUtils;false;copy;(java.lang.String,java.nio.charset.Charset,java.io.OutputStream);;Argument[0];Argument[2];taint",
"org.springframework.util;StreamUtils;false;copyRange;;;Argument[0];Argument[1];taint",
"org.springframework.util;StreamUtils;false;copyToByteArray;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StreamUtils;false;copyToString;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;addStringToArray;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.springframework.util;StringUtils;false;addStringToArray;;;Argument[1];ArrayElement of ReturnValue;value",
"org.springframework.util;StringUtils;false;applyRelativePath;;;Argument[0..1];ReturnValue;taint",
"org.springframework.util;StringUtils;false;arrayToCommaDelimitedString;;;ArrayElement of Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;arrayToDelimitedString;;;ArrayElement of Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;arrayToDelimitedString;;;Argument[1];ReturnValue;taint",
"org.springframework.util;StringUtils;false;capitalize;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;cleanPath;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;collectionToCommaDelimitedString;;;Element of Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;collectionToDelimitedString;;;Element of Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;collectionToDelimitedString;;;Argument[1..3];ReturnValue;taint",
"org.springframework.util;StringUtils;false;commaDelimitedListToSet;;;Argument[0];Element of ReturnValue;taint",
"org.springframework.util;StringUtils;false;commaDelimitedListToStringArray;;;Argument[0];ArrayElement of ReturnValue;taint",
"org.springframework.util;StringUtils;false;concatenateStringArrays;;;ArrayElement of Argument[0..1];ArrayElement of ReturnValue;taint",
"org.springframework.util;StringUtils;false;delete;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;deleteAny;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;delimitedListToStringArray;;;Argument[0];ArrayElement of ReturnValue;taint",
"org.springframework.util;StringUtils;false;getFilename;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;getFilenameExtension;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;mergeStringArrays;;;ArrayElement of Argument[0..1];ArrayElement of ReturnValue;value",
"org.springframework.util;StringUtils;false;quote;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;quoteIfString;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;removeDuplicateStrings;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.springframework.util;StringUtils;false;replace;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;replace;;;Argument[2];ReturnValue;taint",
"org.springframework.util;StringUtils;false;sortStringArray;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"org.springframework.util;StringUtils;false;split;;;Argument[0];ArrayElement of ReturnValue;taint",
"org.springframework.util;StringUtils;false;splitArrayElementsIntoProperties;;;ArrayElement of Argument[0];MapKey of ReturnValue;taint",
"org.springframework.util;StringUtils;false;splitArrayElementsIntoProperties;;;ArrayElement of Argument[0];MapValue of ReturnValue;taint",
"org.springframework.util;StringUtils;false;stripFilenameExtension;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;tokenizeToStringArray;;;Argument[0];ArrayElement of ReturnValue;taint",
"org.springframework.util;StringUtils;false;toStringArray;;;Element of Argument[0];ArrayElement of ReturnValue;value",
"org.springframework.util;StringUtils;false;trimAllWhitespace;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;trimArrayElements;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;taint",
"org.springframework.util;StringUtils;false;trimLeadingCharacter;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;trimLeadingWhitespace;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;trimTrailingCharacter;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;trimTrailingWhitespace;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;trimWhitespace;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;uncapitalize;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;unqualify;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringUtils;false;uriDecode;;;Argument[0];ReturnValue;taint",
"org.springframework.util;StringValueResolver;false;resolveStringValue;;;Argument[0];ReturnValue;taint",
"org.springframework.util;SystemPropertyUtils;false;resolvePlaceholders;;;Argument[0];ReturnValue;taint"
]
}
}

View File

@@ -0,0 +1,25 @@
/** Definitions of flow steps through utility methods of `org.springframework.validation.Errors`. */
import java
private import semmle.code.java.dataflow.ExternalFlow
private class SpringValidationErrorModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.springframework.validation;Errors;true;addAllErrors;;;Argument[0];Argument[-1];taint",
"org.springframework.validation;Errors;true;getAllErrors;;;Argument[-1];ReturnValue;taint",
"org.springframework.validation;Errors;true;getFieldError;;;Argument[-1];ReturnValue;taint",
"org.springframework.validation;Errors;true;getFieldErrors;;;Argument[-1];ReturnValue;taint",
"org.springframework.validation;Errors;true;getGlobalError;;;Argument[-1];ReturnValue;taint",
"org.springframework.validation;Errors;true;getGlobalErrors;;;Argument[-1];ReturnValue;taint",
"org.springframework.validation;Errors;true;reject;;;Argument[0];Argument[-1];taint",
"org.springframework.validation;Errors;true;reject;;;ArrayElement of Argument[1];Argument[-1];taint",
"org.springframework.validation;Errors;true;reject;;;Argument[2];Argument[-1];taint",
"org.springframework.validation;Errors;true;rejectValue;;;Argument[1];Argument[-1];taint",
"org.springframework.validation;Errors;true;rejectValue;;;Argument[3];Argument[-1];taint",
"org.springframework.validation;Errors;true;rejectValue;(java.lang.String,java.lang.String,java.lang.Object[],java.lang.String);;ArrayElement of Argument[2];Argument[-1];taint",
"org.springframework.validation;Errors;true;rejectValue;(java.lang.String,java.lang.String,java.lang.String);;Argument[2];Argument[-1];taint"
]
}
}

View File

@@ -4,6 +4,7 @@
import java
import SpringHttp
private import semmle.code.java.dataflow.ExternalFlow
/** The class `org.springframework.web.client.RestTemplate`. */
class SpringRestTemplate extends Class {
@@ -27,3 +28,26 @@ class SpringWebClient extends Interface {
this.hasQualifiedName("org.springframework.web.reactive.function.client", "WebClient")
}
}
private class UrlOpenSink extends SinkModelCsv {
override predicate row(string row) {
row =
[
"org.springframework.web.client;RestTemplate;false;delete;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;doExecute;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;exchange;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;execute;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;getForEntity;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;getForObject;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;headForHeaders;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;optionsForAllow;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;patchForObject;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;postForEntity;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;postForLocation;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;postForObject;;;Argument[0];open-url",
"org.springframework.web.client;RestTemplate;false;put;;;Argument[0];open-url",
"org.springframework.web.reactive.function.client;WebClient;false;create;;;Argument[0];open-url",
"org.springframework.web.reactive.function.client;WebClient$Builder;false;baseUrl;;;Argument[0];open-url"
]
}
}

View File

@@ -0,0 +1,25 @@
/** Provides models of taint flow in `org.springframework.web.multipart` */
import java
private import semmle.code.java.dataflow.ExternalFlow
private class FlowSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.springframework.web.multipart;MultipartFile;true;getBytes;;;Argument[-1];ReturnValue;taint",
"org.springframework.web.multipart;MultipartFile;true;getInputStream;;;Argument[-1];ReturnValue;taint",
"org.springframework.web.multipart;MultipartFile;true;getName;;;Argument[-1];ReturnValue;taint",
"org.springframework.web.multipart;MultipartFile;true;getOriginalFilename;;;Argument[-1];ReturnValue;taint",
"org.springframework.web.multipart;MultipartFile;true;getResource;;;Argument[-1];ReturnValue;taint",
"org.springframework.web.multipart;MultipartHttpServletRequest;true;getMultipartHeaders;;;Argument[-1];ReturnValue;taint",
"org.springframework.web.multipart;MultipartHttpServletRequest;true;getRequestHeaders;;;Argument[-1];ReturnValue;taint",
"org.springframework.web.multipart;MultipartRequest;true;getFile;;;Argument[-1];ReturnValue;taint",
"org.springframework.web.multipart;MultipartRequest;true;getFileMap;;;Argument[-1];MapValue of ReturnValue;taint",
"org.springframework.web.multipart;MultipartRequest;true;getFileNames;;;Argument[-1];Element of ReturnValue;taint",
"org.springframework.web.multipart;MultipartRequest;true;getFiles;;;Argument[-1];Element of ReturnValue;taint",
"org.springframework.web.multipart;MultipartRequest;true;getMultiFileMap;;;Argument[-1];MapValue of ReturnValue;taint",
"org.springframework.web.multipart;MultipartResolver;true;resolveMultipart;;;Argument[0];ReturnValue;taint"
]
}
}

View File

@@ -0,0 +1,41 @@
/**
* Provides classes and methods common to queries `java/command-line-injection`, `java/command-line-concatenation`
* and their experimental derivatives.
*
* Do not import this from a library file, in order to reduce the risk of
* unintentionally bringing a TaintTracking::Configuration into scope in an unrelated
* query.
*/
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.ExternalProcess
import semmle.code.java.security.CommandArguments
private class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking::Configuration {
RemoteUserInputToArgumentToExecFlowConfig() {
this = "ExecCommon::RemoteUserInputToArgumentToExecFlowConfig"
}
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof ArgumentToExec }
override predicate isSanitizer(DataFlow::Node node) {
node.getType() instanceof PrimitiveType
or
node.getType() instanceof BoxedType
or
isSafeCommandArgument(node.asExpr())
}
}
/**
* Implementation of `ExecTainted.ql`. It is extracted to a QLL
* so that it can be excluded from `ExecUnescaped.ql` to avoid
* reporting overlapping results.
*/
predicate execTainted(DataFlow::PathNode source, DataFlow::PathNode sink, ArgumentToExec execArg) {
exists(RemoteUserInputToArgumentToExecFlowConfig conf |
conf.hasFlowPath(source, sink) and sink.getNode() = DataFlow::exprNode(execArg)
)
}

View File

@@ -2,6 +2,7 @@
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.ExternalFlow
/**
@@ -15,46 +16,6 @@ private class DefaultJexlEvaluationSink extends JexlEvaluationSink {
DefaultJexlEvaluationSink() { sinkNode(this, "jexl") }
}
private class DefaultJexlInjectionSinkModel extends SinkModelCsv {
override predicate row(string row) {
row =
[
// JEXL2
"org.apache.commons.jexl2;JexlEngine;false;getProperty;(JexlContext,Object,String);;Argument[2];jexl",
"org.apache.commons.jexl2;JexlEngine;false;getProperty;(Object,String);;Argument[1];jexl",
"org.apache.commons.jexl2;JexlEngine;false;setProperty;(JexlContext,Object,String,Object);;Argument[2];jexl",
"org.apache.commons.jexl2;JexlEngine;false;setProperty;(Object,String,Object);;Argument[1];jexl",
"org.apache.commons.jexl2;Expression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl2;Expression;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl2;JexlExpression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl2;JexlExpression;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl2;Script;false;execute;;;Argument[-1];jexl",
"org.apache.commons.jexl2;Script;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl2;JexlScript;false;execute;;;Argument[-1];jexl",
"org.apache.commons.jexl2;JexlScript;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl2;UnifiedJEXL$Expression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl2;UnifiedJEXL$Expression;false;prepare;;;Argument[-1];jexl",
"org.apache.commons.jexl2;UnifiedJEXL$Template;false;evaluate;;;Argument[-1];jexl",
// JEXL3
"org.apache.commons.jexl3;JexlEngine;false;getProperty;(JexlContext,Object,String);;Argument[2];jexl",
"org.apache.commons.jexl3;JexlEngine;false;getProperty;(Object,String);;Argument[1];jexl",
"org.apache.commons.jexl3;JexlEngine;false;setProperty;(JexlContext,Object,String);;Argument[2];jexl",
"org.apache.commons.jexl3;JexlEngine;false;setProperty;(Object,String,Object);;Argument[1];jexl",
"org.apache.commons.jexl3;Expression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl3;Expression;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JexlExpression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JexlExpression;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl3;Script;false;execute;;;Argument[-1];jexl",
"org.apache.commons.jexl3;Script;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JexlScript;false;execute;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JexlScript;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JxltEngine$Expression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JxltEngine$Expression;false;prepare;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl"
]
}
}
/**
* A unit class for adding additional taint steps.
*
@@ -77,6 +38,23 @@ private class DefaultJexlInjectionAdditionalTaintStep extends JexlInjectionAddit
}
}
/**
* A taint-tracking configuration for unsafe user input
* that is used to construct and evaluate a JEXL expression.
* It supports both JEXL 2 and 3.
*/
class JexlInjectionConfig extends TaintTracking::Configuration {
JexlInjectionConfig() { this = "JexlInjectionConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink }
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
any(JexlInjectionAdditionalTaintStep c).step(node1, node2)
}
}
/**
* Holds if `n1` to `n2` is a dataflow step that creates a JEXL script using an unsafe engine
* by calling `tainted.createScript(jexlExpr)`.

View File

@@ -0,0 +1,43 @@
/** Provides sink models relating to Expression Langauge (JEXL) injection vulnerabilities. */
private import semmle.code.java.dataflow.ExternalFlow
private class DefaultJexlInjectionSinkModel extends SinkModelCsv {
override predicate row(string row) {
row =
[
// JEXL2
"org.apache.commons.jexl2;JexlEngine;false;getProperty;(JexlContext,Object,String);;Argument[2];jexl",
"org.apache.commons.jexl2;JexlEngine;false;getProperty;(Object,String);;Argument[1];jexl",
"org.apache.commons.jexl2;JexlEngine;false;setProperty;(JexlContext,Object,String,Object);;Argument[2];jexl",
"org.apache.commons.jexl2;JexlEngine;false;setProperty;(Object,String,Object);;Argument[1];jexl",
"org.apache.commons.jexl2;Expression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl2;Expression;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl2;JexlExpression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl2;JexlExpression;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl2;Script;false;execute;;;Argument[-1];jexl",
"org.apache.commons.jexl2;Script;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl2;JexlScript;false;execute;;;Argument[-1];jexl",
"org.apache.commons.jexl2;JexlScript;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl2;UnifiedJEXL$Expression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl2;UnifiedJEXL$Expression;false;prepare;;;Argument[-1];jexl",
"org.apache.commons.jexl2;UnifiedJEXL$Template;false;evaluate;;;Argument[-1];jexl",
// JEXL3
"org.apache.commons.jexl3;JexlEngine;false;getProperty;(JexlContext,Object,String);;Argument[2];jexl",
"org.apache.commons.jexl3;JexlEngine;false;getProperty;(Object,String);;Argument[1];jexl",
"org.apache.commons.jexl3;JexlEngine;false;setProperty;(JexlContext,Object,String);;Argument[2];jexl",
"org.apache.commons.jexl3;JexlEngine;false;setProperty;(Object,String,Object);;Argument[1];jexl",
"org.apache.commons.jexl3;Expression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl3;Expression;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JexlExpression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JexlExpression;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl3;Script;false;execute;;;Argument[-1];jexl",
"org.apache.commons.jexl3;Script;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JexlScript;false;execute;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JexlScript;false;callable;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JxltEngine$Expression;false;evaluate;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JxltEngine$Expression;false;prepare;;;Argument[-1];jexl",
"org.apache.commons.jexl3;JxltEngine$Template;false;evaluate;;;Argument[-1];jexl"
]
}
}

View File

@@ -2,13 +2,8 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.frameworks.Jdbc
import semmle.code.java.frameworks.jOOQ
import semmle.code.java.frameworks.android.SQLite
import semmle.code.java.frameworks.javaee.Persistence
import semmle.code.java.frameworks.SpringJdbc
import semmle.code.java.frameworks.MyBatis
import semmle.code.java.frameworks.Hibernate
import semmle.code.java.dataflow.ExternalFlow
/** A sink for database query language injection vulnerabilities. */
abstract class QueryInjectionSink extends DataFlow::Node { }
@@ -29,28 +24,7 @@ class AdditionalQueryInjectionTaintStep extends Unit {
/** A sink for SQL injection vulnerabilities. */
private class SqlInjectionSink extends QueryInjectionSink {
SqlInjectionSink() {
this.asExpr() instanceof SqlExpr
or
exists(MethodAccess ma, Method m, int index |
ma.getMethod() = m and
if index = -1
then this.asExpr() = ma.getQualifier()
else ma.getArgument(index) = this.asExpr()
|
index = m.(SQLiteRunner).sqlIndex()
or
m instanceof BatchUpdateVarargsMethod
or
index = 0 and jdbcSqlMethod(m)
or
index = 0 and mybatisSqlMethod(m)
or
index = 0 and hibernateSqlMethod(m)
or
index = 0 and jOOQSqlMethod(m)
)
}
SqlInjectionSink() { sinkNode(this, "sql") }
}
/** A sink for Java Persistence Query Language injection vulnerabilities. */

View File

@@ -1,13 +1,8 @@
import java
import semmle.code.java.dataflow.DefUse
import semmle.code.java.dataflow.DataFlow6
/**
* The `java.security.SecureRandom` class.
* Defines classes representing random data sources.
*/
class SecureRandomNumberGenerator extends RefType {
SecureRandomNumberGenerator() { this.hasQualifiedName("java.security", "SecureRandom") }
}
import java
/**
* A method access that returns random data or writes random data to an argument.
@@ -148,149 +143,3 @@ class ApacheCommonsRandomSource extends RandomDataSource {
override Expr getOutput() { result = this }
}
/**
* A method access calling a method declared on `java.security.SecureRandom`
* that returns random data or writes random data to an argument.
*/
class GetRandomData extends StdlibRandomSource {
GetRandomData() { this.getQualifier().getType() instanceof SecureRandomNumberGenerator }
}
private predicate isSeeded(RValue use) {
isSeeding(_, use)
or
exists(GetRandomData da, RValue seeduse |
da.getQualifier() = seeduse and
useUsePair(seeduse, use)
)
}
private class PredictableSeedFlowConfiguration extends DataFlow6::Configuration {
PredictableSeedFlowConfiguration() { this = "Random::PredictableSeedFlowConfiguration" }
override predicate isSource(DataFlow6::Node source) {
source.asExpr() instanceof PredictableSeedExpr
}
override predicate isSink(DataFlow6::Node sink) { isSeeding(sink.asExpr(), _) }
override predicate isAdditionalFlowStep(DataFlow6::Node node1, DataFlow6::Node node2) {
predictableCalcStep(node1.asExpr(), node2.asExpr())
}
}
private predicate predictableCalcStep(Expr e1, Expr e2) {
e2.(BinaryExpr).hasOperands(e1, any(PredictableSeedExpr p))
or
exists(AssignOp a | a = e2 | e1 = a.getDest() and a.getRhs() instanceof PredictableSeedExpr)
or
exists(ConstructorCall cc, TypeNumber t | cc = e2 |
cc.getArgument(0) = e1 and
t.hasSubtype*(cc.getConstructedType())
)
or
exists(Method m, MethodAccess ma |
ma = e2 and
e1 = ma.getQualifier() and
m = ma.getMethod() and
exists(TypeNumber t | hasSubtype*(t, m.getDeclaringType())) and
(
m.getName().matches("to%String") or
m.getName() = "toByteArray" or
m.getName().matches("%Value")
)
)
or
exists(Method m, MethodAccess ma |
ma = e2 and
e1 = ma.getArgument(0) and
m = ma.getMethod() and
exists(TypeNumber t | hasSubtype*(t, m.getDeclaringType())) and
(
m.getName().matches("parse%") or
m.getName().matches("valueOf%") or
m.getName().matches("to%String")
)
)
}
private predicate safelySeeded(RValue use) {
exists(Expr arg |
isSeeding(arg, use) and
not exists(PredictableSeedFlowConfiguration conf | conf.hasFlowToExpr(arg))
)
or
exists(GetRandomData da, RValue seeduse |
da.getQualifier() = seeduse and useUsePair(seeduse, use)
|
not exists(RValue prior | useUsePair(prior, seeduse) | isSeeded(prior))
)
}
predicate unsafelySeeded(RValue use, PredictableSeedExpr source) {
isSeedingSource(_, use, source) and
not safelySeeded(use)
}
private predicate isSeeding(Expr arg, RValue use) {
exists(Expr e, VariableAssign def |
def.getSource() = e and
isSeedingConstruction(e, arg)
|
defUsePair(def, use) or
def.getDestVar().(Field).getAnAccess() = use
)
or
exists(Expr e, RValue seeduse |
e.(MethodAccess).getQualifier() = seeduse and
isRandomSeeding(e, arg) and
useUsePair(seeduse, use)
)
}
private predicate isSeedingSource(Expr arg, RValue use, Expr source) {
isSeeding(arg, use) and
exists(PredictableSeedFlowConfiguration conf |
conf.hasFlow(DataFlow6::exprNode(source), DataFlow6::exprNode(arg))
)
}
private predicate isRandomSeeding(MethodAccess m, Expr arg) {
exists(Method def | m.getMethod() = def |
def.getDeclaringType() instanceof SecureRandomNumberGenerator and
def.getName() = "setSeed" and
arg = m.getArgument(0)
)
}
private predicate isSeedingConstruction(ClassInstanceExpr c, Expr arg) {
c.getConstructedType() instanceof SecureRandomNumberGenerator and
c.getNumArgument() = 1 and
c.getArgument(0) = arg
}
class PredictableSeedExpr extends Expr {
PredictableSeedExpr() {
this.(MethodAccess).getCallee() instanceof ReturnsPredictableExpr
or
this instanceof CompileTimeConstantExpr
or
this.(ArrayCreationExpr).getInit() instanceof PredictableSeedExpr
or
exists(ArrayInit init | init = this |
forall(Expr e | e = init.getAnInit() | e instanceof PredictableSeedExpr)
)
}
}
abstract class ReturnsPredictableExpr extends Method { }
class ReturnsSystemTime extends ReturnsPredictableExpr {
ReturnsSystemTime() {
this.getDeclaringType().hasQualifiedName("java.lang", "System") and
this.hasName("currentTimeMillis")
or
this.getDeclaringType().hasQualifiedName("java.lang", "System") and this.hasName("nanoTime")
}
}

View File

@@ -0,0 +1,173 @@
/** Provides clases and methods shared by randomness-related queries. */
import java
import semmle.code.java.dataflow.DefUse
import semmle.code.java.dataflow.DataFlow6
import RandomDataSource
/**
* The `java.security.SecureRandom` class.
*/
class SecureRandomNumberGenerator extends RefType {
SecureRandomNumberGenerator() { this.hasQualifiedName("java.security", "SecureRandom") }
}
/**
* A method access calling a method declared on `java.security.SecureRandom`
* that returns random data or writes random data to an argument.
*/
class GetRandomData extends StdlibRandomSource {
GetRandomData() { this.getQualifier().getType() instanceof SecureRandomNumberGenerator }
}
private predicate isSeeded(RValue use) {
isSeeding(_, use)
or
exists(GetRandomData da, RValue seeduse |
da.getQualifier() = seeduse and
useUsePair(seeduse, use)
)
}
private class PredictableSeedFlowConfiguration extends DataFlow6::Configuration {
PredictableSeedFlowConfiguration() { this = "Random::PredictableSeedFlowConfiguration" }
override predicate isSource(DataFlow6::Node source) {
source.asExpr() instanceof PredictableSeedExpr
}
override predicate isSink(DataFlow6::Node sink) { isSeeding(sink.asExpr(), _) }
override predicate isAdditionalFlowStep(DataFlow6::Node node1, DataFlow6::Node node2) {
predictableCalcStep(node1.asExpr(), node2.asExpr())
}
}
private predicate predictableCalcStep(Expr e1, Expr e2) {
e2.(BinaryExpr).hasOperands(e1, any(PredictableSeedExpr p))
or
exists(AssignOp a | a = e2 | e1 = a.getDest() and a.getRhs() instanceof PredictableSeedExpr)
or
exists(ConstructorCall cc, TypeNumber t | cc = e2 |
cc.getArgument(0) = e1 and
t.hasSubtype*(cc.getConstructedType())
)
or
exists(Method m, MethodAccess ma |
ma = e2 and
e1 = ma.getQualifier() and
m = ma.getMethod() and
exists(TypeNumber t | hasSubtype*(t, m.getDeclaringType())) and
(
m.getName().matches("to%String") or
m.getName() = "toByteArray" or
m.getName().matches("%Value")
)
)
or
exists(Method m, MethodAccess ma |
ma = e2 and
e1 = ma.getArgument(0) and
m = ma.getMethod() and
exists(TypeNumber t | hasSubtype*(t, m.getDeclaringType())) and
(
m.getName().matches("parse%") or
m.getName().matches("valueOf%") or
m.getName().matches("to%String")
)
)
}
private predicate safelySeeded(RValue use) {
exists(Expr arg |
isSeeding(arg, use) and
not exists(PredictableSeedFlowConfiguration conf | conf.hasFlowToExpr(arg))
)
or
exists(GetRandomData da, RValue seeduse |
da.getQualifier() = seeduse and useUsePair(seeduse, use)
|
not exists(RValue prior | useUsePair(prior, seeduse) | isSeeded(prior))
)
}
/**
* Holds if predictable seed `source` is used to initialise a random-number generator
* used at `use`.
*/
predicate unsafelySeeded(RValue use, PredictableSeedExpr source) {
isSeedingSource(_, use, source) and
not safelySeeded(use)
}
private predicate isSeeding(Expr arg, RValue use) {
exists(Expr e, VariableAssign def |
def.getSource() = e and
isSeedingConstruction(e, arg)
|
defUsePair(def, use) or
def.getDestVar().(Field).getAnAccess() = use
)
or
exists(Expr e, RValue seeduse |
e.(MethodAccess).getQualifier() = seeduse and
isRandomSeeding(e, arg) and
useUsePair(seeduse, use)
)
}
private predicate isSeedingSource(Expr arg, RValue use, Expr source) {
isSeeding(arg, use) and
exists(PredictableSeedFlowConfiguration conf |
conf.hasFlow(DataFlow6::exprNode(source), DataFlow6::exprNode(arg))
)
}
private predicate isRandomSeeding(MethodAccess m, Expr arg) {
exists(Method def | m.getMethod() = def |
def.getDeclaringType() instanceof SecureRandomNumberGenerator and
def.getName() = "setSeed" and
arg = m.getArgument(0)
)
}
private predicate isSeedingConstruction(ClassInstanceExpr c, Expr arg) {
c.getConstructedType() instanceof SecureRandomNumberGenerator and
c.getNumArgument() = 1 and
c.getArgument(0) = arg
}
/**
* A constant, call to a `ReturnsPredictableExpr` method, or an array initialiser
* consisting entirely of the same.
*/
class PredictableSeedExpr extends Expr {
PredictableSeedExpr() {
this.(MethodAccess).getCallee() instanceof ReturnsPredictableExpr
or
this instanceof CompileTimeConstantExpr
or
this.(ArrayCreationExpr).getInit() instanceof PredictableSeedExpr
or
exists(ArrayInit init | init = this |
forall(Expr e | e = init.getAnInit() | e instanceof PredictableSeedExpr)
)
}
}
/**
* A method whose return value is predictable (not necessarily constant).
*
* Extend this class in order that all randomness-related queries should consider the result
* of a particular method predictable when noting bad RNG seeding and related issues.
*/
abstract class ReturnsPredictableExpr extends Method { }
private class ReturnsSystemTime extends ReturnsPredictableExpr {
ReturnsSystemTime() {
this.getDeclaringType().hasQualifiedName("java.lang", "System") and
this.hasName("currentTimeMillis")
or
this.getDeclaringType().hasQualifiedName("java.lang", "System") and this.hasName("nanoTime")
}
}

View File

@@ -0,0 +1,214 @@
/** Provides classes to reason about server-side request forgery (SSRF) attacks. */
import java
import semmle.code.java.frameworks.Networking
import semmle.code.java.frameworks.ApacheHttp
import semmle.code.java.frameworks.spring.Spring
import semmle.code.java.frameworks.JaxWS
import semmle.code.java.frameworks.javase.Http
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.StringFormat
private import semmle.code.java.dataflow.ExternalFlow
/**
* A unit class for adding additional taint steps that are specific to server-side request forgery (SSRF) attacks.
*
* Extend this class to add additional taint steps to the SSRF query.
*/
class RequestForgeryAdditionalTaintStep extends Unit {
/**
* Holds if the step from `pred` to `succ` should be considered a taint
* step for server-side request forgery.
*/
abstract predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ);
}
private class DefaultRequestForgeryAdditionalTaintStep extends RequestForgeryAdditionalTaintStep {
override predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ) {
// propagate to a URI when its host is assigned to
exists(UriCreation c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c)
or
// propagate to a URL when its host is assigned to
exists(UrlConstructorCall c | c.getHostArg() = pred.asExpr() | succ.asExpr() = c)
}
}
/** A data flow sink for server-side request forgery (SSRF) vulnerabilities. */
abstract class RequestForgerySink extends DataFlow::Node { }
private class UrlOpenSinkAsRequestForgerySink extends RequestForgerySink {
UrlOpenSinkAsRequestForgerySink() { sinkNode(this, "open-url") }
}
/** A sanitizer for request forgery vulnerabilities. */
abstract class RequestForgerySanitizer extends DataFlow::Node { }
private class PrimitiveSanitizer extends RequestForgerySanitizer {
PrimitiveSanitizer() {
this.getType() instanceof PrimitiveType or
this.getType() instanceof BoxedType or
this.getType() instanceof NumberType
}
}
private class HostnameSanitizingConstantPrefix extends CompileTimeConstantExpr {
int offset;
HostnameSanitizingConstantPrefix() {
// Matches strings that look like when prepended to untrusted input, they will restrict
// the host or entity addressed: for example, anything containing `?` or `#`, or a slash that
// doesn't appear to be a protocol specifier (e.g. `http://` is not sanitizing), or specifically
// the string "/".
exists(
this.getStringValue()
.regexpFind(".*([?#]|[^?#:/\\\\][/\\\\]).*|[/\\\\][^/\\\\].*|^/$", 0, offset)
)
}
/**
* Gets the offset in this constant string where a sanitizing substring begins.
*/
int getOffset() { result = offset }
}
private Expr getAHostnameSanitizingPrefix() {
result instanceof HostnameSanitizingConstantPrefix
or
result.(AddExpr).getAnOperand() = getAHostnameSanitizingPrefix()
}
private class StringBuilderAppend extends MethodAccess {
StringBuilderAppend() {
this.getMethod().getDeclaringType() instanceof StringBuildingType and
this.getMethod().hasName("append")
}
}
private class StringBuilderConstructorOrAppend extends Call {
StringBuilderConstructorOrAppend() {
this instanceof StringBuilderAppend or
this.(ClassInstanceExpr).getConstructedType() instanceof StringBuildingType
}
}
private Expr getQualifier(Expr e) { result = e.(MethodAccess).getQualifier() }
/**
* An extension of `StringBuilderVar` that also accounts for strings appended in StringBuilder/Buffer's constructor
* and in `append` calls chained onto the constructor call.
*
* The original `StringBuilderVar` doesn't care about these because it is designed to model taint, and
* in taint rules terms these are not needed, as the connection between construction, appends and the
* eventual `toString` is more obvious.
*/
private class StringBuilderVarExt extends StringBuilderVar {
/**
* Returns a first assignment after this StringBuilderVar is first assigned.
*
* For example, for `StringBuilder sbv = new StringBuilder("1").append("2"); sbv.append("3").append("4");`
* this returns the append of `"3"`.
*/
private StringBuilderAppend getAFirstAppendAfterAssignment() {
result = this.getAnAppend() and not result = this.getNextAppend(_)
}
/**
* Gets the next `append` after `prev`, where `prev` is, perhaps after some more `append` or other
* chained calls, assigned to this `StringBuilderVar`.
*/
private StringBuilderAppend getNextAssignmentChainedAppend(StringBuilderConstructorOrAppend prev) {
getQualifier*(result) = this.getAnAssignedValue() and
result.getQualifier() = prev
}
/**
* Get a constructor call or `append` call that contributes a string to this string builder.
*/
StringBuilderConstructorOrAppend getAConstructorOrAppend() {
exists(this.getNextAssignmentChainedAppend(result)) or
result = this.getAnAssignedValue() or
result = this.getAnAppend()
}
/**
* Like `StringBuilderVar.getNextAppend`, except including appends and constructors directly
* assigned to this `StringBuilderVar`.
*/
private StringBuilderAppend getNextAppendIncludingAssignmentChains(
StringBuilderConstructorOrAppend prev
) {
result = getNextAssignmentChainedAppend(prev)
or
prev = this.getAnAssignedValue() and
result = this.getAFirstAppendAfterAssignment()
or
result = this.getNextAppend(prev)
}
/**
* Implements `StringBuilderVarExt.getNextAppendIncludingAssignmentChains+(prev)`.
*/
pragma[nomagic]
StringBuilderAppend getSubsequentAppendIncludingAssignmentChains(
StringBuilderConstructorOrAppend prev
) {
result = this.getNextAppendIncludingAssignmentChains(prev) or
result =
this.getSubsequentAppendIncludingAssignmentChains(this.getNextAppendIncludingAssignmentChains(prev))
}
}
/**
* An expression that is sanitized because it is concatenated onto a string that looks like
* a hostname or a URL separator, preventing the appended string from arbitrarily controlling
* the addressed server.
*/
private class HostnameSanitizedExpr extends Expr {
HostnameSanitizedExpr() {
// Sanitize expressions that come after a sanitizing prefix in a tree of string additions:
this =
any(AddExpr add | add.getLeftOperand() = getAHostnameSanitizingPrefix()).getRightOperand()
or
// Sanitize expressions that come after a sanitizing prefix in a sequence of StringBuilder operations:
exists(
StringBuilderConstructorOrAppend appendSanitizingConstant,
StringBuilderAppend subsequentAppend, StringBuilderVarExt v
|
appendSanitizingConstant = v.getAConstructorOrAppend() and
appendSanitizingConstant.getArgument(0) = getAHostnameSanitizingPrefix() and
v.getSubsequentAppendIncludingAssignmentChains(appendSanitizingConstant) = subsequentAppend and
this = subsequentAppend.getArgument(0)
)
or
// Sanitize expressions that come after a sanitizing prefix in the args to a format call:
exists(
FormattingCall formatCall, FormatString formatString, HostnameSanitizingConstantPrefix prefix,
int sanitizedFromOffset, int laterOffset, int sanitizedArg
|
formatString = unique(FormatString fs | fs = formatCall.getAFormatString()) and
(
// A sanitizing argument comes before this:
exists(int argIdx |
formatCall.getArgumentToBeFormatted(argIdx) = prefix and
sanitizedFromOffset = formatString.getAnArgUsageOffset(argIdx)
)
or
// The format string itself sanitizes subsequent arguments:
formatString = prefix.getStringValue() and
sanitizedFromOffset = prefix.getOffset()
) and
laterOffset > sanitizedFromOffset and
laterOffset = formatString.getAnArgUsageOffset(sanitizedArg) and
this = formatCall.getArgumentToBeFormatted(sanitizedArg)
)
}
}
/**
* A value that is the result of prepending a string that prevents any value from controlling the
* host of a URL.
*/
private class HostnameSantizer extends RequestForgerySanitizer {
HostnameSantizer() { this.asExpr() instanceof HostnameSanitizedExpr }
}

View File

@@ -0,0 +1,31 @@
/**
* Provides a taint-tracking configuration characterising request-forgery risks.
*
* Only import this directly from .ql files, to avoid the possibility of polluting the Configuration hierarchy accidentally.
*/
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.RequestForgery
/**
* A taint-tracking configuration characterising request-forgery risks.
*/
class RequestForgeryConfiguration extends TaintTracking::Configuration {
RequestForgeryConfiguration() { this = "Server-Side Request Forgery" }
override predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource and
// Exclude results of remote HTTP requests: fetching something else based on that result
// is no worse than following a redirect returned by the remote server, and typically
// we're requesting a resource via https which we trust to only send us to safe URLs.
not source.asExpr().(MethodAccess).getCallee() instanceof URLConnectionGetInputStreamMethod
}
override predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink }
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
any(RequestForgeryAdditionalTaintStep r).propagatesTaint(pred, succ)
}
override predicate isSanitizer(DataFlow::Node node) { node instanceof RequestForgerySanitizer }
}

View File

@@ -0,0 +1,86 @@
/**
* Provides utility predicates to spot variable names, parameter names, and string literals that suggest deliberately insecure settings.
*/
import java
import semmle.code.java.controlflow.Guards
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSources
/**
* A kind of flag that may indicate security expectations regarding the code it guards.
*/
abstract class FlagKind extends string {
bindingset[this]
FlagKind() { any() }
/**
* Gets a flag name of this type.
*/
bindingset[result]
abstract string getAFlagName();
/** Gets a node representing a (likely) security flag. */
DataFlow::Node getAFlag() {
exists(DataFlow::Node flag |
exists(VarAccess v | v.getVariable().getName() = getAFlagName() |
flag.asExpr() = v and v.getType() instanceof FlagType
)
or
exists(StringLiteral s | s.getRepresentedString() = getAFlagName() | flag.asExpr() = s)
or
exists(MethodAccess ma | ma.getMethod().getName() = getAFlagName() |
flag.asExpr() = ma and
ma.getType() instanceof FlagType
)
|
flagFlowStep*(flag, result)
)
}
}
/**
* Flags suggesting an optional feature, perhaps deliberately insecure.
*/
private class SecurityFeatureFlag extends FlagKind {
SecurityFeatureFlag() { this = "SecurityFeatureFlag" }
bindingset[result]
override string getAFlagName() { result.regexpMatch("(?i).*(secure|(en|dis)able).*") }
}
/**
* A flag has to either be of type `String`, `boolean` or `Boolean`.
*/
private class FlagType extends Type {
FlagType() {
this instanceof TypeString
or
this instanceof BooleanType
}
}
/**
* Holds if there is local flow from `node1` to `node2` either due to standard data-flow steps or the
* following custom flow steps:
* 1. `Boolean.parseBoolean(taintedValue)` taints the return value of `parseBoolean`.
* 2. A call to an `EnvReadMethod` such as `System.getProperty` where a tainted value is used as an argument.
* The return value of such a method is then tainted.
*/
private predicate flagFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
DataFlow::localFlowStep(node1, node2)
or
exists(MethodAccess ma | ma.getMethod() = any(EnvReadMethod m) |
ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr()
)
or
exists(MethodAccess ma |
ma.getMethod().hasName("parseBoolean") and
ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Boolean")
|
ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr()
)
}
/** Gets a guard that represents a (likely) security feature-flag check. */
Guard getASecurityFeatureFlagGuard() { result = any(SecurityFeatureFlag flag).getAFlag().asExpr() }

View File

@@ -2,6 +2,11 @@ import semmle.code.java.frameworks.Kryo
import semmle.code.java.frameworks.XStream
import semmle.code.java.frameworks.SnakeYaml
import semmle.code.java.frameworks.FastJson
import semmle.code.java.frameworks.JYaml
import semmle.code.java.frameworks.JsonIo
import semmle.code.java.frameworks.YamlBeans
import semmle.code.java.frameworks.HessianBurlap
import semmle.code.java.frameworks.Castor
import semmle.code.java.frameworks.apache.Lang
class ObjectInputStreamReadObjectMethod extends Method {
@@ -140,6 +145,23 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) {
ma.getMethod() instanceof FastJsonParseMethod and
not fastJsonLooksSafe() and
sink = ma.getArgument(0)
or
ma.getMethod() instanceof JYamlLoaderUnsafeLoadMethod and
sink = ma.getArgument(0)
or
ma.getMethod() instanceof JsonIoJsonToJavaMethod and
sink = ma.getArgument(0)
or
ma.getMethod() instanceof JsonIoReadObjectMethod and
sink = ma.getQualifier()
or
ma.getMethod() instanceof YamlBeansReaderReadMethod and sink = ma.getQualifier()
or
ma.getMethod() instanceof UnsafeHessianInputReadObjectMethod and sink = ma.getQualifier()
or
ma.getMethod() instanceof CastorUnmarshalMethod and sink = ma.getAnArgument()
or
ma.getMethod() instanceof BurlapInputReadObjectMethod and sink = ma.getQualifier()
)
}

View File

@@ -2,12 +2,19 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.frameworks.Servlets
import semmle.code.java.frameworks.ApacheHttp
private import semmle.code.java.frameworks.JaxWS
/** A URL redirection sink */
/** A URL redirection sink. */
abstract class UrlRedirectSink extends DataFlow::Node { }
/** A default sink represeting methods susceptible to URL redirection attacks. */
private class DefaultUrlRedirectSink extends UrlRedirectSink {
DefaultUrlRedirectSink() { sinkNode(this, "url-redirect") }
}
/** A Servlet URL redirection sink. */
private class ServletUrlRedirectSink extends UrlRedirectSink {
ServletUrlRedirectSink() {

View File

@@ -29,18 +29,6 @@ class XssAdditionalTaintStep extends Unit {
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
/** CSV sink models representing methods susceptible to XSS attacks. */
private class DefaultXssSinkModel extends SinkModelCsv {
override predicate row(string row) {
row =
[
"android.webkit;WebView;false;loadData;;;Argument[0];xss",
"android.webkit;WebView;false;loadUrl;;;Argument[0];xss",
"android.webkit;WebView;false;loadDataWithBaseURL;;;Argument[1];xss"
]
}
}
/** A default sink representing methods susceptible to XSS attacks. */
private class DefaultXssSink extends XssSink {
DefaultXssSink() {

View File

@@ -15,7 +15,7 @@ private string normalize(string path) {
/**
* An XML element that provides convenience access methods
* to retrieve child XML elements named "groupId", "artifactId"
* and "versionID", typically contained in Maven POM XML files.
* and "version", typically contained in Maven POM XML files.
*/
class ProtoPom extends XMLElement {
/** Gets a child XML element named "groupId". */