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

This commit is contained in:
Tony Torralba
2021-06-16 15:44:43 +02:00
committed by GitHub
800 changed files with 15540 additions and 6277 deletions

View File

@@ -73,10 +73,10 @@ class BlockStmt extends Stmt, @block {
/** Gets the last statement in this block. */
Stmt getLastStmt() { result = getStmt(getNumStmt() - 1) }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "{ ... }" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "{ ... }" }
override string getHalsteadID() { result = "BlockStmt" }
override string getAPrimaryQlClass() { result = "BlockStmt" }
@@ -130,14 +130,14 @@ class IfStmt extends ConditionalStmt, @ifstmt {
/** Gets the `else` branch of this `if` statement. */
Stmt getElse() { result.isNthChildOf(this, 2) }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() {
result = "if (...) " + this.getThen().pp() + " else " + this.getElse().pp()
or
not exists(this.getElse()) and result = "if (...) " + this.getThen().pp()
}
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "if (...)" }
override string getHalsteadID() { result = "IfStmt" }
override string getAPrimaryQlClass() { result = "IfStmt" }
@@ -201,10 +201,10 @@ class ForStmt extends ConditionalStmt, @forstmt {
getCondition().getAChildExpr*() = result.getAnAccess()
}
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "for (...;...;...) " + this.getStmt().pp() }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "for (...;...;...)" }
override string getHalsteadID() { result = "ForStmt" }
override string getAPrimaryQlClass() { result = "ForStmt" }
@@ -221,10 +221,10 @@ class EnhancedForStmt extends Stmt, @enhancedforstmt {
/** Gets the body of this enhanced `for` loop. */
Stmt getStmt() { result.getParent() = this }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "for (...) " + this.getStmt().pp() }
override string pp() { result = "for (... : ...) " + this.getStmt().pp() }
override string toString() { result = "for (... : ...)" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string getHalsteadID() { result = "EnhancedForStmt" }
override string getAPrimaryQlClass() { result = "EnhancedForStmt" }
@@ -244,10 +244,10 @@ class WhileStmt extends ConditionalStmt, @whilestmt {
*/
deprecated override Stmt getTrueSuccessor() { result = getStmt() }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "while (...) " + this.getStmt().pp() }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "while (...)" }
override string getHalsteadID() { result = "WhileStmt" }
override string getAPrimaryQlClass() { result = "WhileStmt" }
@@ -267,10 +267,10 @@ class DoStmt extends ConditionalStmt, @dostmt {
*/
deprecated override Stmt getTrueSuccessor() { result = getStmt() }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "do " + this.getStmt().pp() + " while (...)" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "do ... while (...)" }
override string getHalsteadID() { result = "DoStmt" }
override string getAPrimaryQlClass() { result = "DoStmt" }
@@ -356,10 +356,10 @@ class TryStmt extends Stmt, @trystmt {
result = getAResourceExpr().getVariable()
}
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "try " + this.getBlock().pp() + " catch (...)" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "try ..." }
override string getHalsteadID() { result = "TryStmt" }
override string getAPrimaryQlClass() { result = "TryStmt" }
@@ -387,10 +387,10 @@ class CatchClause extends Stmt, @catchclause {
)
}
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "catch (...) " + this.getBlock().pp() }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "catch (...)" }
override string getHalsteadID() { result = "CatchClause" }
override string getAPrimaryQlClass() { result = "CatchClause" }
@@ -422,10 +422,10 @@ class SwitchStmt extends Stmt, @switchstmt {
/** Gets the expression of this `switch` statement. */
Expr getExpr() { result.getParent() = this }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "switch (...)" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "switch (...)" }
override string getHalsteadID() { result = "SwitchStmt" }
override string getAPrimaryQlClass() { result = "SwitchStmt" }
@@ -485,10 +485,10 @@ class ConstCase extends SwitchCase {
*/
Expr getValue(int i) { result.getParent() = this and result.getIndex() = i and i >= 0 }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "case ..." }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "case ..." }
override string getHalsteadID() { result = "ConstCase" }
override string getAPrimaryQlClass() { result = "ConstCase" }
@@ -498,10 +498,10 @@ class ConstCase extends SwitchCase {
class DefaultCase extends SwitchCase {
DefaultCase() { not exists(Expr e | e.getParent() = this | e.getIndex() >= 0) }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "default" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "default" }
override string getHalsteadID() { result = "DefaultCase" }
override string getAPrimaryQlClass() { result = "DefaultCase" }
@@ -515,10 +515,10 @@ class SynchronizedStmt extends Stmt, @synchronizedstmt {
/** Gets the block of this `synchronized` statement. */
Stmt getBlock() { result.getParent() = this }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "synchronized (...) " + this.getBlock().pp() }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "synchronized (...)" }
override string getHalsteadID() { result = "SynchronizedStmt" }
override string getAPrimaryQlClass() { result = "SynchronizedStmt" }
@@ -529,10 +529,10 @@ class ReturnStmt extends Stmt, @returnstmt {
/** Gets the expression returned by this `return` statement, if any. */
Expr getResult() { result.getParent() = this }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "return ..." }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "return ..." }
override string getHalsteadID() { result = "ReturnStmt" }
override string getAPrimaryQlClass() { result = "ReturnStmt" }
@@ -543,10 +543,10 @@ class ThrowStmt extends Stmt, @throwstmt {
/** Gets the expression thrown by this `throw` statement. */
Expr getExpr() { result.getParent() = this }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "throw ..." }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "throw ..." }
override string getHalsteadID() { result = "ThrowStmt" }
/** Gets the type of the expression thrown by this `throw` statement. */
@@ -638,12 +638,12 @@ class BreakStmt extends Stmt, @breakstmt {
/** Holds if this `break` statement has an explicit label. */
predicate hasLabel() { exists(string s | s = this.getLabel()) }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() {
if this.hasLabel() then result = "break " + this.getLabel() else result = "break"
}
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "break" }
override string getHalsteadID() { result = "BreakStmt" }
override string getAPrimaryQlClass() { result = "BreakStmt" }
@@ -660,6 +660,8 @@ class YieldStmt extends Stmt, @yieldstmt {
override string pp() { result = "yield ..." }
override string toString() { result = "yield ..." }
override string getHalsteadID() { result = "YieldStmt" }
override string getAPrimaryQlClass() { result = "YieldStmt" }
@@ -673,12 +675,12 @@ class ContinueStmt extends Stmt, @continuestmt {
/** Holds if this `continue` statement has an explicit label. */
predicate hasLabel() { exists(string s | s = this.getLabel()) }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() {
if this.hasLabel() then result = "continue " + this.getLabel() else result = "continue"
}
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "continue" }
override string getHalsteadID() { result = "ContinueStmt" }
override string getAPrimaryQlClass() { result = "ContinueStmt" }
@@ -686,10 +688,10 @@ class ContinueStmt extends Stmt, @continuestmt {
/** The empty statement. */
class EmptyStmt extends Stmt, @emptystmt {
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = ";" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = ";" }
override string getHalsteadID() { result = "EmptyStmt" }
override string getAPrimaryQlClass() { result = "EmptyStmt" }
@@ -704,10 +706,10 @@ class ExprStmt extends Stmt, @exprstmt {
/** Gets the expression of this expression statement. */
Expr getExpr() { result.getParent() = this }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "...;" }
override string pp() { result = "<Expr>;" }
override string toString() { result = "<Expr>;" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string getHalsteadID() { result = "ExprStmt" }
/** Holds if this statement represents a field declaration with an initializer. */
@@ -733,12 +735,12 @@ class LabeledStmt extends Stmt, @labeledstmt {
/** Gets the label of this labeled statement. */
string getLabel() { namestrings(result, _, this) }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = this.getLabel() + ": " + this.getStmt().pp() }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string getHalsteadID() { result = this.getLabel() + ":" }
override string toString() { result = "<Label>: ..." }
override string getAPrimaryQlClass() { result = "LabeledStmt" }
}
@@ -750,12 +752,12 @@ class AssertStmt extends Stmt, @assertstmt {
/** Gets the assertion message expression, if any. */
Expr getMessage() { exprs(result, _, _, this, _) and result.getIndex() = 1 }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() {
if exists(this.getMessage()) then result = "assert ... : ..." else result = "assert ..."
}
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string toString() { result = "assert ..." }
override string getHalsteadID() { result = "AssertStmt" }
override string getAPrimaryQlClass() { result = "AssertStmt" }
@@ -775,10 +777,10 @@ class LocalVariableDeclStmt extends Stmt, @localvariabledeclstmt {
/** Gets an index of a variable declared in this local variable declaration statement. */
int getAVariableIndex() { exists(getVariable(result)) }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "local variable declaration" }
override string pp() { result = "var ...;" }
override string toString() { result = "var ...;" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string getHalsteadID() { result = "LocalVariableDeclStmt" }
override string getAPrimaryQlClass() { result = "LocalVariableDeclStmt" }
@@ -789,10 +791,10 @@ class LocalClassDeclStmt extends Stmt, @localclassdeclstmt {
/** Gets the local class declared by this statement. */
LocalClass getLocalClass() { isLocalClass(result, this) }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "local class declaration: " + this.getLocalClass().toString() }
override string pp() { result = "class " + this.getLocalClass().toString() }
override string toString() { result = "class ..." }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string getHalsteadID() { result = "LocalClassDeclStmt" }
override string getAPrimaryQlClass() { result = "LocalClassDeclStmt" }
@@ -829,13 +831,10 @@ class ThisConstructorInvocationStmt extends Stmt, ConstructorCall, @constructori
/** Gets the immediately enclosing statement of this constructor invocation. */
override Stmt getEnclosingStmt() { result = this }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "this(...)" }
/** Gets a printable representation of this statement. */
override string toString() { result = pp() }
override string toString() { result = "this(...)" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string getHalsteadID() { result = "ConstructorInvocationStmt" }
override string getAPrimaryQlClass() { result = "ThisConstructorInvocationStmt" }
@@ -873,13 +872,10 @@ class SuperConstructorInvocationStmt extends Stmt, ConstructorCall, @superconstr
/** Gets the immediately enclosing statement of this constructor invocation. */
override Stmt getEnclosingStmt() { result = this }
/** Gets a printable representation of this statement. May include more detail than `toString()`. */
override string pp() { result = "super(...)" }
/** Gets a printable representation of this statement. */
override string toString() { result = pp() }
override string toString() { result = "super(...)" }
/** This statement's Halstead ID (used to compute Halstead metrics). */
override string getHalsteadID() { result = "SuperConstructorInvocationStmt" }
override string getAPrimaryQlClass() { result = "SuperConstructorInvocationStmt" }

View File

@@ -67,6 +67,8 @@
import java
private import semmle.code.java.dataflow.DataFlow::DataFlow
private import internal.DataFlowPrivate
private import internal.FlowSummaryImpl::Private::External
private import internal.FlowSummaryImplSpecific
private import FlowSummary
/**
@@ -74,15 +76,18 @@ private import FlowSummary
* ensuring that they are visible to the taint tracking / data flow library.
*/
private module Frameworks {
private import internal.ContainerFlow
private import semmle.code.java.frameworks.ApacheHttp
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.security.ResponseSplitting
private import semmle.code.java.security.InformationLeak
private import semmle.code.java.security.XSS
private import semmle.code.java.security.LdapInjection
private import semmle.code.java.security.XPath
private import semmle.code.java.security.MvelInjection
private import semmle.code.java.security.JexlInjection
}
private predicate sourceModelCsv(string row) {
@@ -358,7 +363,8 @@ private predicate summaryModel(string row) {
any(SummaryModelCsv s).row(row)
}
private predicate sourceModel(
/** Holds if a source model exists for the given parameters. */
predicate sourceModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind
) {
@@ -376,7 +382,8 @@ private predicate sourceModel(
)
}
private predicate sinkModel(
/** Holds if a sink model exists for the given parameters. */
predicate sinkModel(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string input, string kind
) {
@@ -394,7 +401,8 @@ private predicate sinkModel(
)
}
private predicate summaryModel(
/** Holds if a summary model 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
) {
@@ -481,7 +489,7 @@ module CsvValidation {
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
or
not type.regexpMatch("[a-zA-Z0-9_\\$]+") and
not type.regexpMatch("[a-zA-Z0-9_\\$<>]+") and
msg = "Dubious type \"" + type + "\" in " + pred + " model."
or
not name.regexpMatch("[a-zA-Z0-9_]*") and
@@ -499,10 +507,15 @@ module CsvValidation {
or
summaryModel(_, _, _, _, _, _, input, _, _) and pred = "summary"
|
specSplit(input, part, _) and
not part.regexpMatch("|ReturnValue|ArrayElement|Element|MapKey|MapValue") and
not (part = "Argument" and pred = "sink") and
not parseArg(part, _) and
(
invalidSpecComponent(input, part) and
not part = "" and
not (part = "Argument" and pred = "sink") and
not parseArg(part, _)
or
specSplit(input, part, _) and
parseParam(part, _)
) and
msg = "Unrecognized input specification \"" + part + "\" in " + pred + " model."
)
or
@@ -511,11 +524,9 @@ module CsvValidation {
or
summaryModel(_, _, _, _, _, _, _, output, _) and pred = "summary"
|
specSplit(output, part, _) and
not part.regexpMatch("|ReturnValue|ArrayElement|Element|MapKey|MapValue") and
invalidSpecComponent(output, part) and
not part = "" and
not (part = ["Argument", "Parameter"] and pred = "source") and
not parseArg(part, _) and
not parseParam(part, _) and
msg = "Unrecognized output specification \"" + part + "\" in " + pred + " model."
)
or
@@ -562,7 +573,7 @@ private RefType interpretType(string namespace, string type, boolean subtypes) {
private string paramsStringPart(Callable c, int i) {
i = -1 and result = "("
or
exists(int n, string p | c.getParameterType(n).toString() = p |
exists(int n, string p | c.getParameterType(n).getErasure().toString() = p |
i = 2 * n and result = p
or
i = 2 * n - 1 and result = "," and n != 0
@@ -596,7 +607,8 @@ private Element interpretElement0(
)
}
private Element interpretElement(
/** Gets the source/sink/summary element corresponding to the supplied parameters. */
Element interpretElement(
string namespace, string type, boolean subtypes, string name, string signature, string ext
) {
elementSpec(namespace, type, subtypes, name, signature, ext) and
@@ -607,269 +619,25 @@ private Element interpretElement(
)
}
private predicate sourceElement(Element e, string output, string kind) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind) and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
cached
private module Cached {
/**
* Holds if `node` is specified as a source with the given kind in a CSV flow
* model.
*/
cached
predicate sourceNode(Node node, string kind) {
exists(InterpretNode n | isSourceNode(n, kind) and n.asNode() = node)
}
private predicate sinkElement(Element e, string input, string kind) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind) and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
private predicate summaryElement(Element e, string input, string output, string kind) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind) and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
private string inOutSpec() {
sourceModel(_, _, _, _, _, _, result, _) or
sinkModel(_, _, _, _, _, _, result, _) or
summaryModel(_, _, _, _, _, _, result, _, _) or
summaryModel(_, _, _, _, _, _, _, result, _)
}
private predicate specSplit(string s, string c, int n) {
inOutSpec() = s and s.splitAt(" of ", n) = c
}
private predicate len(string s, int len) { len = 1 + max(int n | specSplit(s, _, n)) }
private string getLast(string s) {
exists(int len |
len(s, len) and
specSplit(s, result, len - 1)
)
}
private predicate parseParam(string c, int n) {
specSplit(_, c, _) and
(
c.regexpCapture("Parameter\\[([-0-9]+)\\]", 1).toInt() = n
or
exists(int n1, int n2 |
c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and
c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and
n = [n1 .. n2]
)
)
}
private predicate parseArg(string c, int n) {
specSplit(_, c, _) and
(
c.regexpCapture("Argument\\[([-0-9]+)\\]", 1).toInt() = n
or
exists(int n1, int n2 |
c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and
c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and
n = [n1 .. n2]
)
)
}
private predicate inputNeedsReference(string c) {
c = "Argument" or
parseArg(c, _)
}
private predicate outputNeedsReference(string c) {
c = "Argument" or
parseArg(c, _) or
c = "ReturnValue"
}
private predicate sourceElementRef(Top ref, string output, string kind) {
exists(Element e |
sourceElement(e, output, kind) and
if outputNeedsReference(getLast(output))
then ref.(Call).getCallee().getSourceDeclaration() = e
else ref = e
)
}
private predicate sinkElementRef(Top ref, string input, string kind) {
exists(Element e |
sinkElement(e, input, kind) and
if inputNeedsReference(getLast(input))
then ref.(Call).getCallee().getSourceDeclaration() = e
else ref = e
)
}
private predicate summaryElementRef(Top ref, string input, string output, string kind) {
exists(Element e |
summaryElement(e, input, output, kind) and
if inputNeedsReference(getLast(input))
then ref.(Call).getCallee().getSourceDeclaration() = e
else ref = e
)
}
private SummaryComponent interpretComponent(string c) {
specSplit(_, c, _) and
(
exists(int pos | parseArg(c, pos) and result = SummaryComponent::argument(pos))
or
exists(int pos | parseParam(c, pos) and result = SummaryComponent::parameter(pos))
or
c = "ReturnValue" and result = SummaryComponent::return()
or
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))
)
}
private predicate interpretSpec(string spec, int idx, SummaryComponentStack stack) {
exists(string c |
summaryElement(_, spec, _, _) or
summaryElement(_, _, spec, _)
|
len(spec, idx + 1) and
specSplit(spec, c, idx) and
stack = SummaryComponentStack::singleton(interpretComponent(c))
)
or
exists(SummaryComponent head, SummaryComponentStack tail |
interpretSpec(spec, idx, head, tail) and
stack = SummaryComponentStack::push(head, tail)
)
}
private predicate interpretSpec(
string output, int idx, SummaryComponent head, SummaryComponentStack tail
) {
exists(string c |
interpretSpec(output, idx + 1, tail) and
specSplit(output, c, idx) and
head = interpretComponent(c)
)
}
private class MkStack extends RequiredSummaryComponentStack {
MkStack() { interpretSpec(_, _, _, this) }
override predicate required(SummaryComponent c) { interpretSpec(_, _, c, this) }
}
private class SummarizedCallableExternal extends SummarizedCallable {
SummarizedCallableExternal() { summaryElement(this, _, _, _) }
override predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) {
exists(string inSpec, string outSpec, string kind |
summaryElement(this, inSpec, outSpec, kind) and
interpretSpec(inSpec, 0, input) and
interpretSpec(outSpec, 0, output)
|
kind = "value" and preservesValue = true
or
kind = "taint" and preservesValue = false
)
/**
* Holds if `node` is specified as a sink with the given kind in a CSV flow
* model.
*/
cached
predicate sinkNode(Node node, string kind) {
exists(InterpretNode n | isSinkNode(n, kind) and n.asNode() = node)
}
}
private newtype TAstOrNode =
TAst(Top t) or
TNode(Node n)
private predicate interpretOutput(string output, int idx, Top ref, TAstOrNode node) {
(
sourceElementRef(ref, output, _) or
summaryElementRef(ref, _, output, _)
) and
len(output, idx) and
node = TAst(ref)
or
exists(Top mid, string c, Node n |
interpretOutput(output, idx + 1, ref, TAst(mid)) and
specSplit(output, c, idx) and
node = TNode(n)
|
exists(int pos | n.(PostUpdateNode).getPreUpdateNode().(ArgumentNode).argumentOf(mid, pos) |
c = "Argument" or parseArg(c, pos)
)
or
exists(int pos | n.(ParameterNode).isParameterOf(mid, pos) |
c = "Parameter" or parseParam(c, pos)
)
or
(c = "Parameter" or c = "") and
n.asParameter() = mid
or
c = "ReturnValue" and
n.asExpr().(Call) = mid
or
c = "" and
n.asExpr().(FieldRead).getField() = mid
)
}
private predicate interpretInput(string input, int idx, Top ref, TAstOrNode node) {
(
sinkElementRef(ref, input, _) or
summaryElementRef(ref, input, _, _)
) and
len(input, idx) and
node = TAst(ref)
or
exists(Top mid, string c, Node n |
interpretInput(input, idx + 1, ref, TAst(mid)) and
specSplit(input, c, idx) and
node = TNode(n)
|
exists(int pos | n.(ArgumentNode).argumentOf(mid, pos) | c = "Argument" or parseArg(c, pos))
or
exists(ReturnStmt ret |
c = "ReturnValue" and
n.asExpr() = ret.getResult() and
mid = ret.getEnclosingCallable()
)
or
exists(FieldWrite fw |
c = "" and
fw.getField() = mid and
n.asExpr() = fw.getRHS()
)
)
}
/**
* Holds if `node` is specified as a source with the given kind in a CSV flow
* model.
*/
predicate sourceNode(Node node, string kind) {
exists(Top ref, string output |
sourceElementRef(ref, output, kind) and
interpretOutput(output, 0, ref, TNode(node))
)
}
/**
* Holds if `node` is specified as a sink with the given kind in a CSV flow
* model.
*/
predicate sinkNode(Node node, string kind) {
exists(Top ref, string input |
sinkElementRef(ref, input, kind) and
interpretInput(input, 0, ref, TNode(node))
)
}
import Cached

View File

@@ -1,6 +1,9 @@
import java
import semmle.code.java.Collections
import semmle.code.java.Maps
private import semmle.code.java.dataflow.SSA
private import DataFlowUtil
private import semmle.code.java.dataflow.ExternalFlow
private class EntryType extends RefType {
EntryType() {
@@ -88,6 +91,286 @@ class ContainerType extends RefType {
}
}
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.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",
"java.util;ListIterator;true;previous;;;Element of Argument[-1];ReturnValue;value",
"java.util;ListIterator;true;add;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;ListIterator;true;set;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;Enumeration;true;asIterator;;;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Enumeration;true;nextElement;;;Element of Argument[-1];ReturnValue;value",
"java.util;Map;true;computeIfAbsent;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map;true;computeIfAbsent;;;ReturnValue of Argument[1];ReturnValue;value",
"java.util;Map;true;computeIfAbsent;;;ReturnValue of Argument[1];MapValue of Argument[-1];value",
"java.util;Map;true;entrySet;;;MapValue of Argument[-1];MapValue of Element of ReturnValue;value",
"java.util;Map;true;entrySet;;;MapKey of Argument[-1];MapKey of Element of ReturnValue;value",
"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;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",
"java.util;Map;true;remove;(Object);;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map;true;replace;(Object,Object);;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map;true;replace;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
"java.util;Map;true;replace;(Object,Object);;Argument[1];MapValue of Argument[-1];value",
"java.util;Map;true;replace;(Object,Object,Object);;Argument[0];MapKey of Argument[-1];value",
"java.util;Map;true;replace;(Object,Object,Object);;Argument[2];MapValue of Argument[-1];value",
"java.util;Map;true;keySet;();;MapKey of Argument[-1];Element of ReturnValue;value",
"java.util;Map;true;values;();;MapValue of Argument[-1];Element of ReturnValue;value",
"java.util;Map;true;merge;(Object,Object,BiFunction);;Argument[1];MapValue of Argument[-1];value",
"java.util;Map;true;putAll;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
"java.util;Map;true;putAll;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
"java.util;Collection;true;parallelStream;();;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Collection;true;stream;();;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Collection;true;toArray;;;Element of Argument[-1];ArrayElement of ReturnValue;value",
"java.util;Collection;true;toArray;;;Element of Argument[-1];ArrayElement of Argument[0];value",
"java.util;Collection;true;add;;;Argument[0];Element of Argument[-1];value",
"java.util;Collection;true;addAll;;;Element of Argument[0];Element of Argument[-1];value",
"java.util;List;true;get;(int);;Element of Argument[-1];ReturnValue;value",
"java.util;List;true;listIterator;;;Element of Argument[-1];Element of ReturnValue;value",
"java.util;List;true;remove;(int);;Element of Argument[-1];ReturnValue;value",
"java.util;List;true;set;(int,Object);;Element of Argument[-1];ReturnValue;value",
"java.util;List;true;set;(int,Object);;Argument[1];Element of Argument[-1];value",
"java.util;List;true;subList;;;Element of Argument[-1];Element of ReturnValue;value",
"java.util;List;true;add;(int,Object);;Argument[1];Element of Argument[-1];value",
"java.util;List;true;addAll;(int,Collection);;Element of Argument[1];Element of Argument[-1];value",
"java.util;Vector;true;elementAt;(int);;Element of Argument[-1];ReturnValue;value",
"java.util;Vector;true;elements;();;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Vector;true;firstElement;();;Element of Argument[-1];ReturnValue;value",
"java.util;Vector;true;lastElement;();;Element of Argument[-1];ReturnValue;value",
"java.util;Vector;true;addElement;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;Vector;true;insertElementAt;(Object,int);;Argument[0];Element of Argument[-1];value",
"java.util;Vector;true;setElementAt;(Object,int);;Argument[0];Element of Argument[-1];value",
"java.util;Vector;true;copyInto;(Object[]);;Element of Argument[-1];ArrayElement of Argument[0];value",
"java.util;Stack;true;peek;();;Element of Argument[-1];ReturnValue;value",
"java.util;Stack;true;pop;();;Element of Argument[-1];ReturnValue;value",
"java.util;Stack;true;push;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;Queue;true;element;();;Element of Argument[-1];ReturnValue;value",
"java.util;Queue;true;peek;();;Element of Argument[-1];ReturnValue;value",
"java.util;Queue;true;poll;();;Element of Argument[-1];ReturnValue;value",
"java.util;Queue;true;remove;();;Element of Argument[-1];ReturnValue;value",
"java.util;Queue;true;offer;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;Deque;true;descendingIterator;();;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Deque;true;getFirst;();;Element of Argument[-1];ReturnValue;value",
"java.util;Deque;true;getLast;();;Element of Argument[-1];ReturnValue;value",
"java.util;Deque;true;peekFirst;();;Element of Argument[-1];ReturnValue;value",
"java.util;Deque;true;peekLast;();;Element of Argument[-1];ReturnValue;value",
"java.util;Deque;true;pollFirst;();;Element of Argument[-1];ReturnValue;value",
"java.util;Deque;true;pollLast;();;Element of Argument[-1];ReturnValue;value",
"java.util;Deque;true;pop;();;Element of Argument[-1];ReturnValue;value",
"java.util;Deque;true;removeFirst;();;Element of Argument[-1];ReturnValue;value",
"java.util;Deque;true;removeLast;();;Element of Argument[-1];ReturnValue;value",
"java.util;Deque;true;push;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;Deque;true;offerLast;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;Deque;true;offerFirst;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;Deque;true;addLast;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;Deque;true;addFirst;(Object);;Argument[0];Element of Argument[-1];value",
"java.util.concurrent;BlockingDeque;true;pollFirst;(long,TimeUnit);;Element of Argument[-1];ReturnValue;value",
"java.util.concurrent;BlockingDeque;true;pollLast;(long,TimeUnit);;Element of Argument[-1];ReturnValue;value",
"java.util.concurrent;BlockingDeque;true;takeFirst;();;Element of Argument[-1];ReturnValue;value",
"java.util.concurrent;BlockingDeque;true;takeLast;();;Element of Argument[-1];ReturnValue;value",
"java.util.concurrent;BlockingQueue;true;poll;(long,TimeUnit);;Element of Argument[-1];ReturnValue;value",
"java.util.concurrent;BlockingQueue;true;take;();;Element of Argument[-1];ReturnValue;value",
"java.util.concurrent;BlockingQueue;true;offer;(Object,long,TimeUnit);;Argument[0];Element of Argument[-1];value",
"java.util.concurrent;BlockingQueue;true;put;(Object);;Argument[0];Element of Argument[-1];value",
"java.util.concurrent;BlockingDeque;true;offerLast;(Object,long,TimeUnit);;Argument[0];Element of Argument[-1];value",
"java.util.concurrent;BlockingDeque;true;offerFirst;(Object,long,TimeUnit);;Argument[0];Element of Argument[-1];value",
"java.util.concurrent;BlockingDeque;true;putLast;(Object);;Argument[0];Element of Argument[-1];value",
"java.util.concurrent;BlockingDeque;true;putFirst;(Object);;Argument[0];Element of Argument[-1];value",
"java.util.concurrent;BlockingQueue;true;drainTo;(Collection,int);;Element of Argument[-1];Element of Argument[0];value",
"java.util.concurrent;BlockingQueue;true;drainTo;(Collection);;Element of Argument[-1];Element of Argument[0];value",
"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;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",
"java.util;Dictionary;true;remove;(Object);;MapValue of Argument[-1];ReturnValue;value",
"java.util;NavigableMap;true;ceilingEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;ceilingEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;descendingMap;();;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;descendingMap;();;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;firstEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;firstEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;floorEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;floorEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;headMap;(Object,boolean);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;headMap;(Object,boolean);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;higherEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;higherEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;lastEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;lastEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;lowerEntry;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;lowerEntry;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;pollFirstEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;pollFirstEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;pollLastEntry;();;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;pollLastEntry;();;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;subMap;(Object,boolean,Object,boolean);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableMap;true;tailMap;(Object,boolean);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;NavigableMap;true;tailMap;(Object,boolean);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;NavigableSet;true;ceiling;(Object);;Element of Argument[-1];ReturnValue;value",
"java.util;NavigableSet;true;descendingIterator;();;Element of Argument[-1];Element of ReturnValue;value",
"java.util;NavigableSet;true;descendingSet;();;Element of Argument[-1];Element of ReturnValue;value",
"java.util;NavigableSet;true;floor;(Object);;Element of Argument[-1];ReturnValue;value",
"java.util;NavigableSet;true;headSet;(Object,boolean);;Element of Argument[-1];Element of ReturnValue;value",
"java.util;NavigableSet;true;higher;(Object);;Element of Argument[-1];ReturnValue;value",
"java.util;NavigableSet;true;lower;(Object);;Element of Argument[-1];ReturnValue;value",
"java.util;NavigableSet;true;pollFirst;();;Element of Argument[-1];ReturnValue;value",
"java.util;NavigableSet;true;pollLast;();;Element of Argument[-1];ReturnValue;value",
"java.util;NavigableSet;true;subSet;(Object,boolean,Object,boolean);;Element of Argument[-1];Element of ReturnValue;value",
"java.util;NavigableSet;true;tailSet;(Object,boolean);;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Scanner;true;next;(Pattern);;Argument[-1];ReturnValue;taint",
"java.util;Scanner;true;next;(String);;Argument[-1];ReturnValue;taint",
"java.util;SortedMap;true;headMap;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;SortedMap;true;headMap;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;SortedMap;true;subMap;(Object,Object);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;SortedMap;true;subMap;(Object,Object);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;SortedMap;true;tailMap;(Object);;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.util;SortedMap;true;tailMap;(Object);;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.util;SortedSet;true;first;();;Element of Argument[-1];ReturnValue;value",
"java.util;SortedSet;true;headSet;(Object);;Element of Argument[-1];Element of ReturnValue;value",
"java.util;SortedSet;true;last;();;Element of Argument[-1];ReturnValue;value",
"java.util;SortedSet;true;subSet;(Object,Object);;Element of Argument[-1];Element of ReturnValue;value",
"java.util;SortedSet;true;tailSet;(Object);;Element of Argument[-1];Element of ReturnValue;value",
"java.util.concurrent;TransferQueue;true;tryTransfer;(Object,long,TimeUnit);;Argument[0];Element of Argument[-1];value",
"java.util.concurrent;TransferQueue;true;transfer;(Object);;Argument[0];Element of Argument[-1];value",
"java.util.concurrent;TransferQueue;true;tryTransfer;(Object);;Argument[0];Element of Argument[-1];value",
"java.util;List;false;copyOf;(Collection);;Element of Argument[0];Element of ReturnValue;value",
"java.util;List;false;of;(Object[]);;ArrayElement of Argument[0];Element of ReturnValue;value",
"java.util;List;false;of;(Object);;Argument[0];Element of ReturnValue;value",
"java.util;List;false;of;(Object,Object);;Argument[0..1];Element of ReturnValue;value",
"java.util;List;false;of;(Object,Object,Object);;Argument[0..2];Element of ReturnValue;value",
"java.util;List;false;of;(Object,Object,Object,Object);;Argument[0..3];Element of ReturnValue;value",
"java.util;List;false;of;(Object,Object,Object,Object,Object);;Argument[0..4];Element of ReturnValue;value",
"java.util;List;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0..5];Element of ReturnValue;value",
"java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0..6];Element of ReturnValue;value",
"java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];Element of ReturnValue;value",
"java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];Element of ReturnValue;value",
"java.util;List;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];Element of ReturnValue;value",
"java.util;Map;false;copyOf;(Map);;MapKey of Argument[0];MapKey of ReturnValue;value",
"java.util;Map;false;copyOf;(Map);;MapValue of Argument[0];MapValue of ReturnValue;value",
"java.util;Map;false;entry;(Object,Object);;Argument[0];MapKey of ReturnValue;value",
"java.util;Map;false;entry;(Object,Object);;Argument[1];MapValue of ReturnValue;value",
"java.util;Map;false;of;;;Argument[0];MapKey of ReturnValue;value",
"java.util;Map;false;of;;;Argument[1];MapValue of ReturnValue;value",
"java.util;Map;false;of;;;Argument[2];MapKey of ReturnValue;value",
"java.util;Map;false;of;;;Argument[3];MapValue of ReturnValue;value",
"java.util;Map;false;of;;;Argument[4];MapKey of ReturnValue;value",
"java.util;Map;false;of;;;Argument[5];MapValue of ReturnValue;value",
"java.util;Map;false;of;;;Argument[6];MapKey of ReturnValue;value",
"java.util;Map;false;of;;;Argument[7];MapValue of ReturnValue;value",
"java.util;Map;false;of;;;Argument[8];MapKey of ReturnValue;value",
"java.util;Map;false;of;;;Argument[9];MapValue of ReturnValue;value",
"java.util;Map;false;of;;;Argument[10];MapKey of ReturnValue;value",
"java.util;Map;false;of;;;Argument[11];MapValue of ReturnValue;value",
"java.util;Map;false;of;;;Argument[12];MapKey of ReturnValue;value",
"java.util;Map;false;of;;;Argument[13];MapValue of ReturnValue;value",
"java.util;Map;false;of;;;Argument[14];MapKey of ReturnValue;value",
"java.util;Map;false;of;;;Argument[15];MapValue of ReturnValue;value",
"java.util;Map;false;of;;;Argument[16];MapKey of ReturnValue;value",
"java.util;Map;false;of;;;Argument[17];MapValue of ReturnValue;value",
"java.util;Map;false;of;;;Argument[18];MapKey of ReturnValue;value",
"java.util;Map;false;of;;;Argument[19];MapValue of ReturnValue;value",
"java.util;Map;false;ofEntries;;;MapKey of ArrayElement of Argument[0];MapKey of ReturnValue;value",
"java.util;Map;false;ofEntries;;;MapValue of ArrayElement of Argument[0];MapValue of ReturnValue;value",
"java.util;Set;false;copyOf;(Collection);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Set;false;of;(Object[]);;ArrayElement of Argument[0];Element of ReturnValue;value",
"java.util;Set;false;of;(Object);;Argument[0];Element of ReturnValue;value",
"java.util;Set;false;of;(Object,Object);;Argument[0..1];Element of ReturnValue;value",
"java.util;Set;false;of;(Object,Object,Object);;Argument[0..2];Element of ReturnValue;value",
"java.util;Set;false;of;(Object,Object,Object,Object);;Argument[0..3];Element of ReturnValue;value",
"java.util;Set;false;of;(Object,Object,Object,Object,Object);;Argument[0..4];Element of ReturnValue;value",
"java.util;Set;false;of;(Object,Object,Object,Object,Object,Object);;Argument[0..5];Element of ReturnValue;value",
"java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object);;Argument[0..6];Element of ReturnValue;value",
"java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..7];Element of ReturnValue;value",
"java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..8];Element of ReturnValue;value",
"java.util;Set;false;of;(Object,Object,Object,Object,Object,Object,Object,Object,Object,Object);;Argument[0..9];Element of ReturnValue;value",
"java.util;Arrays;false;stream;;;ArrayElement of Argument[0];Element of ReturnValue;value",
"java.util;Arrays;false;spliterator;;;ArrayElement of Argument[0];Element of ReturnValue;value",
"java.util;Arrays;false;copyOfRange;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"java.util;Arrays;false;copyOf;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;value",
"java.util;Collections;false;list;(Enumeration);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;enumeration;(Collection);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;nCopies;(int,Object);;Argument[1];Element of ReturnValue;value",
"java.util;Collections;false;singletonMap;(Object,Object);;Argument[0];MapKey of ReturnValue;value",
"java.util;Collections;false;singletonMap;(Object,Object);;Argument[1];MapValue of ReturnValue;value",
"java.util;Collections;false;singletonList;(Object);;Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;singleton;(Object);;Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;MapKey of Argument[0];MapKey of ReturnValue;value",
"java.util;Collections;false;checkedNavigableMap;(NavigableMap,Class,Class);;MapValue of Argument[0];MapValue of ReturnValue;value",
"java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;MapKey of Argument[0];MapKey of ReturnValue;value",
"java.util;Collections;false;checkedSortedMap;(SortedMap,Class,Class);;MapValue of Argument[0];MapValue of ReturnValue;value",
"java.util;Collections;false;checkedMap;(Map,Class,Class);;MapKey of Argument[0];MapKey of ReturnValue;value",
"java.util;Collections;false;checkedMap;(Map,Class,Class);;MapValue of Argument[0];MapValue of ReturnValue;value",
"java.util;Collections;false;checkedList;(List,Class);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;checkedNavigableSet;(NavigableSet,Class);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;checkedSortedSet;(SortedSet,Class);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;checkedSet;(Set,Class);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;checkedCollection;(Collection,Class);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;MapKey of Argument[0];MapKey of ReturnValue;value",
"java.util;Collections;false;synchronizedNavigableMap;(NavigableMap);;MapValue of Argument[0];MapValue of ReturnValue;value",
"java.util;Collections;false;synchronizedSortedMap;(SortedMap);;MapKey of Argument[0];MapKey of ReturnValue;value",
"java.util;Collections;false;synchronizedSortedMap;(SortedMap);;MapValue of Argument[0];MapValue of ReturnValue;value",
"java.util;Collections;false;synchronizedMap;(Map);;MapKey of Argument[0];MapKey of ReturnValue;value",
"java.util;Collections;false;synchronizedMap;(Map);;MapValue of Argument[0];MapValue of ReturnValue;value",
"java.util;Collections;false;synchronizedList;(List);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;synchronizedNavigableSet;(NavigableSet);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;synchronizedSortedSet;(SortedSet);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;synchronizedSet;(Set);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;synchronizedCollection;(Collection);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;MapKey of Argument[0];MapKey of ReturnValue;value",
"java.util;Collections;false;unmodifiableNavigableMap;(NavigableMap);;MapValue of Argument[0];MapValue of ReturnValue;value",
"java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;MapKey of Argument[0];MapKey of ReturnValue;value",
"java.util;Collections;false;unmodifiableSortedMap;(SortedMap);;MapValue of Argument[0];MapValue of ReturnValue;value",
"java.util;Collections;false;unmodifiableMap;(Map);;MapKey of Argument[0];MapKey of ReturnValue;value",
"java.util;Collections;false;unmodifiableMap;(Map);;MapValue of Argument[0];MapValue of ReturnValue;value",
"java.util;Collections;false;unmodifiableList;(List);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;unmodifiableNavigableSet;(NavigableSet);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;unmodifiableSortedSet;(SortedSet);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;unmodifiableSet;(Set);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;unmodifiableCollection;(Collection);;Element of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;max;;;Element of Argument[0];ReturnValue;value",
"java.util;Collections;false;min;;;Element of Argument[0];ReturnValue;value",
"java.util;Arrays;false;fill;(Object[],int,int,Object);;Argument[3];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(Object[],Object);;Argument[1];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(float[],int,int,float);;Argument[3];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(float[],float);;Argument[1];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(double[],int,int,double);;Argument[3];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(double[],double);;Argument[1];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(boolean[],int,int,boolean);;Argument[3];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(boolean[],boolean);;Argument[1];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(byte[],int,int,byte);;Argument[3];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(byte[],byte);;Argument[1];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(char[],int,int,char);;Argument[3];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(char[],char);;Argument[1];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(short[],int,int,short);;Argument[3];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(short[],short);;Argument[1];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(int[],int,int,int);;Argument[3];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(int[],int);;Argument[1];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(long[],int,int,long);;Argument[3];ArrayElement of Argument[0];value",
"java.util;Arrays;false;fill;(long[],long);;Argument[1];ArrayElement of Argument[0];value",
"java.util;Collections;false;replaceAll;(List,Object,Object);;Argument[2];Element of Argument[0];value",
"java.util;Collections;false;copy;(List,List);;Element of Argument[1];Element of Argument[0];value",
"java.util;Collections;false;fill;(List,Object);;Argument[1];Element of Argument[0];value",
"java.util;Arrays;false;asList;;;ArrayElement of Argument[0];Element of ReturnValue;value",
"java.util;Collections;false;addAll;(Collection,Object[]);;ArrayElement of Argument[1];Element of Argument[0];value"
]
}
}
private predicate taintPreservingQualifierToMethod(Method m) {
// java.util.Map.Entry
m.getDeclaringType() instanceof EntryType and
@@ -426,3 +709,58 @@ predicate containerStep(Expr n1, Expr n2) {
containerReturnValueStep(n1, n2) or
containerUpdateStep(n1, n2)
}
/**
* Holds if the step from `node1` to `node2` stores a value in an array.
* This covers array assignments and initializers as well as implicit array
* creations for varargs.
*/
predicate arrayStoreStep(Node node1, Node node2) {
exists(Argument arg |
node1.asExpr() = arg and
arg.isVararg() and
node2.(ImplicitVarargsArray).getCall() = arg.getCall()
)
or
node2.asExpr().(ArrayInit).getAnInit() = node1.asExpr()
or
exists(Assignment assign | assign.getSource() = node1.asExpr() |
node2.(PostUpdateNode).getPreUpdateNode().asExpr() = assign.getDest().(ArrayAccess).getArray()
)
}
private predicate enhancedForStmtStep(Node node1, Node node2, Type containerType) {
exists(EnhancedForStmt for, Expr e, SsaExplicitUpdate v |
for.getExpr() = e and
node1.asExpr() = e and
containerType = e.getType() and
v.getDefiningExpr() = for.getVariable() and
v.getAFirstUse() = node2.asExpr()
)
}
/**
* Holds if the step from `node1` to `node2` reads a value from an array.
* This covers ordinary array reads as well as array iteration through enhanced
* `for` statements.
*/
predicate arrayReadStep(Node node1, Node node2, Type elemType) {
exists(ArrayAccess aa |
aa.getArray() = node1.asExpr() and
aa.getType() = elemType and
node2.asExpr() = aa
)
or
exists(Array arr |
enhancedForStmtStep(node1, node2, arr) and
arr.getComponentType() = elemType
)
}
/**
* Holds if the step from `node1` to `node2` reads a value from a collection.
* This only covers iteration through enhanced `for` statements.
*/
predicate collectionReadStep(Node node1, Node node2) {
enhancedForStmtStep(node1, node2, any(Type t | not t instanceof Array))
}

View File

@@ -4,6 +4,7 @@ private import DataFlowImplCommon
private import DataFlowDispatch
private import semmle.code.java.controlflow.Guards
private import semmle.code.java.dataflow.SSA
private import ContainerFlow
private import FlowSummaryImpl as FlowSummaryImpl
import DataFlowNodes::Private
@@ -137,13 +138,15 @@ class MapValueContent extends Content, TMapValueContent {
* Thus, `node2` references an object with a field `f` that contains the
* value of `node1`.
*/
predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
predicate storeStep(Node node1, Content f, Node node2) {
exists(FieldAccess fa |
instanceFieldAssign(node1.asExpr(), fa) and
node2.getPreUpdateNode() = getFieldQualifier(fa) and
node2.(PostUpdateNode).getPreUpdateNode() = getFieldQualifier(fa) and
f.(FieldContent).getField() = fa.getField()
)
or
f instanceof ArrayContent and arrayStoreStep(node1, node2)
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, f, node2)
}
@@ -171,6 +174,10 @@ predicate readStep(Node node1, Content f, Node node2) {
node2.asExpr() = get
)
or
f instanceof ArrayContent and arrayReadStep(node1, node2, _)
or
f instanceof CollectionContent and collectionReadStep(node1, node2)
or
FlowSummaryImpl::Private::Steps::summaryReadStep(node1, f, node2)
}
@@ -296,7 +303,9 @@ predicate isUnreachableInCall(Node n, DataFlowCall call) {
// which is used in a guard
param.getAUse() = guard and
// which controls `n` with the opposite value of `arg`
guard.controls(n.asExpr().getBasicBlock(), arg.getBooleanValue().booleanNot())
guard
.controls(n.asExpr().getBasicBlock(),
pragma[only_bind_out](arg.getBooleanValue()).booleanNot())
)
}

View File

@@ -9,10 +9,11 @@ private import semmle.code.java.controlflow.Guards
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSteps
private import semmle.code.java.dataflow.FlowSummary
import semmle.code.java.dataflow.InstanceAccess
private import semmle.code.java.dataflow.InstanceAccess
private import FlowSummaryImpl as FlowSummaryImpl
private import TaintTrackingUtil as TaintTrackingUtil
import DataFlowNodes::Public
import semmle.code.Unit
/** Holds if `n` is an access to an unqualified `this` at `cfgnode`. */
private predicate thisAccess(Node n, ControlFlowNode cfgnode) {
@@ -144,6 +145,8 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
or
node2.asExpr().(AssignExpr).getSource() = node1.asExpr()
or
node2.asExpr().(ArrayCreationExpr).getInit() = node1.asExpr()
or
exists(MethodAccess ma, ValuePreservingMethod m, int argNo |
ma.getCallee().getSourceDeclaration() = m and m.returnsValue(argNo)
|

View File

@@ -9,6 +9,7 @@
private import FlowSummaryImplSpecific
private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public
private import DataFlowImplCommon as DataFlowImplCommon
/** Provides classes and predicates for defining flow summaries. */
module Public {
@@ -178,7 +179,6 @@ module Public {
*/
module Private {
private import Public
private import DataFlowImplCommon as DataFlowImplCommon
newtype TSummaryComponent =
TContentSummaryComponent(Content c) or
@@ -580,88 +580,227 @@ module Private {
* summaries into a `SummarizedCallable`s.
*/
module External {
/**
* Provides a means of translating an externally (e.g., CSV) defined flow
* summary into a `SummarizedCallable`.
*/
abstract class ExternalSummaryCompilation extends string {
bindingset[this]
ExternalSummaryCompilation() { any() }
/** Holds if this flow summary is for callable `c`. */
abstract predicate callable(DataFlowCallable c, boolean preservesValue);
/** Holds if the `i`th input component is `c`. */
abstract predicate input(int i, SummaryComponent c);
/** Holds if the `i`th output component is `c`. */
abstract predicate output(int i, SummaryComponent c);
/**
* Holds if the input components starting from index `i` translate into `suffix`.
*/
final predicate translateInput(int i, SummaryComponentStack suffix) {
exists(SummaryComponent comp | this.input(i, comp) |
i = max(int j | this.input(j, _)) and
suffix = TSingletonSummaryComponentStack(comp)
or
exists(TSummaryComponent head, SummaryComponentStack tail |
this.translateInputCons(i, head, tail) and
suffix = TConsSummaryComponentStack(head, tail)
)
)
}
final predicate translateInputCons(int i, SummaryComponent head, SummaryComponentStack tail) {
this.input(i, head) and
this.translateInput(i + 1, tail)
}
/**
* Holds if the output components starting from index `i` translate into `suffix`.
*/
predicate translateOutput(int i, SummaryComponentStack suffix) {
exists(SummaryComponent comp | this.output(i, comp) |
i = max(int j | this.output(j, _)) and
suffix = TSingletonSummaryComponentStack(comp)
or
exists(TSummaryComponent head, SummaryComponentStack tail |
this.translateOutputCons(i, head, tail) and
suffix = TConsSummaryComponentStack(head, tail)
)
)
}
predicate translateOutputCons(int i, SummaryComponent head, SummaryComponentStack tail) {
this.output(i, head) and
this.translateOutput(i + 1, tail)
}
/** Holds if `spec` is a relevant external specification. */
private predicate relevantSpec(string spec) {
summaryElement(_, spec, _, _) or
summaryElement(_, _, spec, _) or
sourceElement(_, spec, _) or
sinkElement(_, spec, _)
}
private class ExternalRequiredSummaryComponentStack extends RequiredSummaryComponentStack {
private SummaryComponent head;
/** Holds if the `n`th component of specification `s` is `c`. */
predicate specSplit(string s, string c, int n) { relevantSpec(s) and s.splitAt(" of ", n) = c }
ExternalRequiredSummaryComponentStack() {
any(ExternalSummaryCompilation s).translateInputCons(_, head, this) or
any(ExternalSummaryCompilation s).translateOutputCons(_, head, this)
}
/** Holds if specification `s` has length `len`. */
predicate specLength(string s, int len) { len = 1 + max(int n | specSplit(s, _, n)) }
override predicate required(SummaryComponent c) { c = head }
/** Gets the last component of specification `s`. */
string specLast(string s) {
exists(int len |
specLength(s, len) and
specSplit(s, result, len - 1)
)
}
class ExternalSummarizedCallableAdaptor extends SummarizedCallable {
ExternalSummarizedCallableAdaptor() { any(ExternalSummaryCompilation s).callable(this, _) }
/** Holds if specification component `c` parses as parameter `n`. */
predicate parseParam(string c, int n) {
specSplit(_, c, _) and
(
c.regexpCapture("Parameter\\[([-0-9]+)\\]", 1).toInt() = n
or
exists(int n1, int n2 |
c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and
c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and
n = [n1 .. n2]
)
)
}
/** Holds if specification component `c` parses as argument `n`. */
predicate parseArg(string c, int n) {
specSplit(_, c, _) and
(
c.regexpCapture("Argument\\[([-0-9]+)\\]", 1).toInt() = n
or
exists(int n1, int n2 |
c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and
c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and
n = [n1 .. n2]
)
)
}
private SummaryComponent interpretComponent(string c) {
specSplit(_, c, _) and
(
exists(int pos | parseArg(c, pos) and result = SummaryComponent::argument(pos))
or
exists(int pos | parseParam(c, pos) and result = SummaryComponent::parameter(pos))
or
c = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind())
or
result = interpretComponentSpecific(c)
)
}
private predicate interpretSpec(string spec, int idx, SummaryComponentStack stack) {
exists(string c |
relevantSpec(spec) and
specLength(spec, idx + 1) and
specSplit(spec, c, idx) and
stack = SummaryComponentStack::singleton(interpretComponent(c))
)
or
exists(SummaryComponent head, SummaryComponentStack tail |
interpretSpec(spec, idx, head, tail) and
stack = SummaryComponentStack::push(head, tail)
)
}
private predicate interpretSpec(
string output, int idx, SummaryComponent head, SummaryComponentStack tail
) {
exists(string c |
interpretSpec(output, idx + 1, tail) and
specSplit(output, c, idx) and
head = interpretComponent(c)
)
}
private class MkStack extends RequiredSummaryComponentStack {
MkStack() { interpretSpec(_, _, _, this) }
override predicate required(SummaryComponent c) { interpretSpec(_, _, c, this) }
}
private class SummarizedCallableExternal extends SummarizedCallable {
SummarizedCallableExternal() { summaryElement(this, _, _, _) }
override predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) {
exists(ExternalSummaryCompilation s |
s.callable(this, preservesValue) and
s.translateInput(0, input) and
s.translateOutput(0, output)
exists(string inSpec, string outSpec, string kind |
summaryElement(this, inSpec, outSpec, kind) and
interpretSpec(inSpec, 0, input) and
interpretSpec(outSpec, 0, output)
|
kind = "value" and preservesValue = true
or
kind = "taint" and preservesValue = false
)
}
}
/** Holds if component `c` of specification `spec` cannot be parsed. */
predicate invalidSpecComponent(string spec, string c) {
specSplit(spec, c, _) and
not exists(interpretComponent(c))
}
private predicate inputNeedsReference(string c) {
c = "Argument" or
parseArg(c, _)
}
private predicate outputNeedsReference(string c) {
c = "Argument" or
parseArg(c, _) or
c = "ReturnValue"
}
private predicate sourceElementRef(InterpretNode ref, string output, string kind) {
exists(SourceOrSinkElement e |
sourceElement(e, output, kind) and
if outputNeedsReference(specLast(output))
then e = ref.getCallTarget()
else e = ref.asElement()
)
}
private predicate sinkElementRef(InterpretNode ref, string input, string kind) {
exists(SourceOrSinkElement e |
sinkElement(e, input, kind) and
if inputNeedsReference(specLast(input))
then e = ref.getCallTarget()
else e = ref.asElement()
)
}
private predicate interpretOutput(string output, int idx, InterpretNode ref, InterpretNode node) {
sourceElementRef(ref, output, _) and
specLength(output, idx) and
node = ref
or
exists(InterpretNode mid, string c |
interpretOutput(output, idx + 1, ref, mid) and
specSplit(output, c, idx)
|
exists(int pos |
node.asNode()
.(PostUpdateNode)
.getPreUpdateNode()
.(ArgumentNode)
.argumentOf(mid.asCall(), pos)
|
c = "Argument" or parseArg(c, pos)
)
or
exists(int pos | node.asNode().(ParameterNode).isParameterOf(mid.asCallable(), pos) |
c = "Parameter" or parseParam(c, pos)
)
or
c = "ReturnValue" and
node.asNode() = getAnOutNode(mid.asCall(), getReturnValueKind())
or
interpretOutputSpecific(c, mid, node)
)
}
private predicate interpretInput(string input, int idx, InterpretNode ref, InterpretNode node) {
sinkElementRef(ref, input, _) and
specLength(input, idx) and
node = ref
or
exists(InterpretNode mid, string c |
interpretInput(input, idx + 1, ref, mid) and
specSplit(input, c, idx)
|
exists(int pos | node.asNode().(ArgumentNode).argumentOf(mid.asCall(), pos) |
c = "Argument" or parseArg(c, pos)
)
or
exists(ReturnNode ret |
c = "ReturnValue" and
ret = node.asNode() and
ret.getKind() = getReturnValueKind() and
mid.asCallable() = DataFlowImplCommon::getNodeEnclosingCallable(ret)
)
or
interpretInputSpecific(c, mid, node)
)
}
/**
* Holds if `node` is specified as a source with the given kind in a CSV flow
* model.
*/
predicate isSourceNode(InterpretNode node, string kind) {
exists(InterpretNode ref, string output |
sourceElementRef(ref, output, kind) and
interpretOutput(output, 0, ref, node)
)
}
/**
* Holds if `node` is specified as a sink with the given kind in a CSV flow
* model.
*/
predicate isSinkNode(InterpretNode node, string kind) {
exists(InterpretNode ref, string input |
sinkElementRef(ref, input, kind) and
interpretInput(input, 0, ref, node)
)
}
}
/** Provides a query predicate for outputting a set of relevant flow summaries. */

View File

@@ -7,6 +7,7 @@ private import DataFlowPrivate
private import DataFlowUtil
private import FlowSummaryImpl::Private
private import FlowSummaryImpl::Public
private import semmle.code.java.dataflow.ExternalFlow
private module FlowSummaries {
private import semmle.code.java.dataflow.FlowSummary as F
@@ -30,6 +31,12 @@ DataFlowType getContentType(Content c) {
or
c instanceof ArrayContent and
result instanceof TypeObject
or
c instanceof MapKeyContent and
result instanceof TypeObject
or
c instanceof MapValueContent and
result instanceof TypeObject
}
/** Gets the return type of kind `rk` for callable `c`. */
@@ -49,3 +56,120 @@ DataFlowType getCallbackParameterType(DataFlowType t, int i) { none() }
* callback of type `t`.
*/
DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { none() }
/**
* Holds if an external flow summary exists for `c` with input specification
* `input`, output specification `output`, and kind `kind`.
*/
predicate summaryElement(DataFlowCallable c, string input, string output, string kind) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind) and
c = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
/** 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))
}
class SourceOrSinkElement = Top;
/**
* Holds if an external source specification exists for `e` with output specification
* `output` and kind `kind`.
*/
predicate sourceElement(SourceOrSinkElement e, string output, string kind) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind) and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
/**
* Holds if an external sink specification exists for `e` with input specification
* `input` and kind `kind`.
*/
predicate sinkElement(SourceOrSinkElement e, string input, string kind) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind) and
e = interpretElement(namespace, type, subtypes, name, signature, ext)
)
}
/** Gets the return kind corresponding to specification `"ReturnValue"`. */
ReturnKind getReturnValueKind() { any() }
private newtype TInterpretNode =
TElement(SourceOrSinkElement n) or
TNode(Node n)
/** An entity used to interpret a source/sink specification. */
class InterpretNode extends TInterpretNode {
/** Gets the element that this node corresponds to, if any. */
SourceOrSinkElement asElement() { this = TElement(result) }
/** Gets the data-flow node that this node corresponds to, if any. */
Node asNode() { this = TNode(result) }
/** Gets the call that this node corresponds to, if any. */
DataFlowCall asCall() { result = this.asElement() }
/** Gets the callable that this node corresponds to, if any. */
DataFlowCallable asCallable() { result = this.asElement() }
/** Gets the target of this call, if any. */
Callable getCallTarget() { result = this.asCall().getCallee().getSourceDeclaration() }
/** Gets a textual representation of this node. */
string toString() {
result = this.asElement().toString()
or
result = this.asNode().toString()
}
/** Gets the location of this node. */
Location getLocation() {
result = this.asElement().getLocation()
or
result = this.asNode().getLocation()
}
}
/** Provides additional sink specification logic required for annotations. */
pragma[inline]
predicate interpretOutputSpecific(string c, InterpretNode mid, InterpretNode node) {
exists(Node n, Top ast |
n = node.asNode() and
ast = mid.asElement()
|
(c = "Parameter" or c = "") and
node.asNode().asParameter() = mid.asElement()
or
c = "" and
n.asExpr().(FieldRead).getField() = ast
)
}
/** Provides additional source specification logic required for annotations. */
pragma[inline]
predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode n) {
exists(FieldWrite fw |
c = "" and
fw.getField() = mid.asElement() and
n.asNode().asExpr() = fw.getRHS()
)
}

View File

@@ -14,6 +14,7 @@ private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.internal.DataFlowPrivate
import semmle.code.java.dataflow.FlowSteps
private import FlowSummaryImpl as FlowSummaryImpl
private import semmle.code.java.frameworks.JaxWS
/**
* Holds if taint can flow from `src` to `sink` in zero or more
@@ -60,10 +61,16 @@ private module Cached {
localAdditionalTaintUpdateStep(src.asExpr(),
sink.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr())
or
exists(Argument arg |
src.asExpr() = arg and
arg.isVararg() and
sink.(DataFlow::ImplicitVarargsArray).getCall() = arg.getCall()
exists(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
)
or
FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false)
@@ -93,6 +100,92 @@ private module Cached {
import Cached
/**
* 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.
*/
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))
)
}
}
}
/**
* Holds if taint can flow in one local step from `src` to `sink` excluding
* local data flow steps. That is, `src` and `sink` are likely to represent
@@ -103,22 +196,8 @@ private predicate localAdditionalTaintExprStep(Expr src, Expr sink) {
or
sink.(AssignAddExpr).getSource() = src and sink.getType() instanceof TypeString
or
sink.(ArrayCreationExpr).getInit() = src
or
sink.(ArrayInit).getAnInit() = src
or
sink.(ArrayAccess).getArray() = src
or
sink.(LogicExpr).getAnOperand() = src
or
exists(EnhancedForStmt for, SsaExplicitUpdate v |
for.getExpr() = src and
v.getDefiningExpr() = for.getVariable() and
v.getAFirstUse() = sink
)
or
containerReturnValueStep(src, sink)
or
constructorStep(src, sink)
or
qualifierToMethodStep(src, sink)
@@ -141,12 +220,6 @@ private predicate localAdditionalTaintExprStep(Expr src, Expr sink) {
* This is restricted to cases where the step updates the value of `sink`.
*/
private predicate localAdditionalTaintUpdateStep(Expr src, Expr sink) {
exists(Assignment assign | assign.getSource() = src |
sink = assign.getDest().(ArrayAccess).getArray()
)
or
containerUpdateStep(src, sink)
or
qualifierToArgumentStep(src, sink)
or
argToArgStep(src, sink)
@@ -277,6 +350,10 @@ private predicate taintPreservingQualifierToMethod(Method m) {
)
or
m.(TaintPreservingCallable).returnsTaintFrom(-1)
or
exists(JaxRsResourceMethod resourceMethod |
m.(GetterMethod).getDeclaringType() = resourceMethod.getAParameter().getType()
)
}
private class StringReplaceMethod extends TaintPreservingCallable {

View File

@@ -11,6 +11,7 @@ private import VirtualDispatch
private import semmle.code.java.dataflow.internal.BaseSSA
private import semmle.code.java.dataflow.internal.DataFlowUtil
private import semmle.code.java.dataflow.internal.DataFlowPrivate
private import semmle.code.java.dataflow.InstanceAccess
private import semmle.code.java.Collections
private import semmle.code.java.Maps

View File

@@ -14,6 +14,7 @@ private import semmle.code.java.dataflow.internal.BaseSSA
private import semmle.code.java.dataflow.internal.DataFlowUtil
private import semmle.code.java.dataflow.internal.DataFlowPrivate
private import semmle.code.java.dataflow.internal.ContainerFlow
private import semmle.code.java.dataflow.InstanceAccess
/**
* Gets a viable dispatch target for `ma`. This is the input dispatch relation.

View File

@@ -165,14 +165,17 @@ private class ApacheHttpFlowStep extends SummaryModelCsv {
"org.apache.http.util;EncodingUtils;true;getAsciiString;;;Argument[0];ReturnValue;taint",
"org.apache.http.util;EncodingUtils;true;getBytes;(String,String);;Argument[0];ReturnValue;taint",
"org.apache.http.util;EncodingUtils;true;getString;;;Argument[0];ReturnValue;taint",
"org.apache.http.util;Args;true;containsNoBlanks;(T,String);;Argument[0];ReturnValue;value",
"org.apache.http.util;Args;true;notNull;(T,String);;Argument[0];ReturnValue;value",
"org.apache.http.util;Args;true;notEmpty;(T,String);;Argument[0];ReturnValue;value",
"org.apache.http.util;Args;true;notBlank;(T,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.util;Args;true;containsNoBlanks;(T,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.util;Args;true;notNull;(T,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.util;Args;true;notEmpty;(T,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.util;Args;true;notBlank;(T,String);;Argument[0];ReturnValue;value",
"org.apache.http.util;Args;true;containsNoBlanks;(CharSequence,String);;Argument[0];ReturnValue;value",
"org.apache.http.util;Args;true;notNull;(Object,String);;Argument[0];ReturnValue;value",
"org.apache.http.util;Args;true;notEmpty;(CharSequence,String);;Argument[0];ReturnValue;value",
"org.apache.http.util;Args;true;notEmpty;(Collection,String);;Argument[0];ReturnValue;value",
"org.apache.http.util;Args;true;notBlank;(CharSequence,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.util;Args;true;containsNoBlanks;(CharSequence,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.util;Args;true;notNull;(Object,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.util;Args;true;notEmpty;(Collection,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.util;Args;true;notEmpty;(CharSequence,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.util;Args;true;notEmpty;(Object,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.util;Args;true;notBlank;(CharSequence,String);;Argument[0];ReturnValue;value",
"org.apache.hc.core5.http.io.entity;HttpEntities;true;create;;;Argument[0];ReturnValue;taint",
"org.apache.hc.core5.http.io.entity;HttpEntities;true;createGzipped;;;Argument[0];ReturnValue;taint",
"org.apache.hc.core5.http.io.entity;HttpEntities;true;createUrlEncoded;;;Argument[0];ReturnValue;taint",

View File

@@ -94,29 +94,33 @@ private class ApacheStringUtilsModel extends SummaryModelCsv {
"org.apache.commons.lang3;StringUtils;false;defaultString;;;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;deleteWhitespace;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;difference;;;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;firstNonBlank;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;firstNonEmpty;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;firstNonBlank;;;ArrayElement of Argument[0];ReturnValue;value",
"org.apache.commons.lang3;StringUtils;false;firstNonEmpty;;;ArrayElement of Argument[0];ReturnValue;value",
"org.apache.commons.lang3;StringUtils;false;getBytes;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;getCommonPrefix;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;getCommonPrefix;;;ArrayElement of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;getDigits;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;getIfBlank;;;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;getIfEmpty;;;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(char[],char);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(char[],char,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,char);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,java.lang.String);;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[]);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String);;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,char);;Element of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,java.lang.String);;Element of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Iterable,java.lang.String);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[]);;ArrayElement of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char);;ArrayElement of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],char,int,int);;ArrayElement of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String);;ArrayElement of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String,int,int);;ArrayElement of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.lang.Object[],java.lang.String,int,int);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,char);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,java.lang.String);;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.util.List,char,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.util.List,java.lang.String,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,char);;Element of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,java.lang.String);;Element of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.util.Iterator,java.lang.String);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.util.List,char,int,int);;Element of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.util.List,java.lang.String,int,int);;Element of Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;join;(java.util.List,java.lang.String,int,int);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;joinWith;;;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;joinWith;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;joinWith;;;ArrayElement of Argument[1];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;left;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;leftPad;(java.lang.String,int,java.lang.String);;Argument[2];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;leftPad;;;Argument[0];ReturnValue;taint",
@@ -148,9 +152,9 @@ private class ApacheStringUtilsModel extends SummaryModelCsv {
"org.apache.commons.lang3;StringUtils;false;replaceChars;(java.lang.String,java.lang.String,java.lang.String);;Argument[2];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;replaceChars;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;replaceEach;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;replaceEach;;;Argument[2];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;replaceEach;;;ArrayElement of Argument[2];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;replaceEachRepeatedly;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;replaceEachRepeatedly;;;Argument[2];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;replaceEachRepeatedly;;;ArrayElement of Argument[2];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;replaceFirst;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;replaceFirst;;;Argument[2];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;replaceIgnoreCase;;;Argument[0];ReturnValue;taint",
@@ -182,7 +186,7 @@ private class ApacheStringUtilsModel extends SummaryModelCsv {
"org.apache.commons.lang3;StringUtils;false;strip;(java.lang.String);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;strip;(java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;stripAccents;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;stripAll;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;stripAll;;;ArrayElement of Argument[0];ArrayElement of ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;stripEnd;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;stripStart;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3;StringUtils;false;stripToEmpty;;;Argument[0];ReturnValue;taint",
@@ -229,7 +233,8 @@ private class ApacheStrBuilderModel extends SummaryModelCsv {
"org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint",
@@ -238,7 +243,9 @@ private class ApacheStrBuilderModel extends SummaryModelCsv {
"org.apache.commons.lang3.text;StrBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;append;(org.apache.commons.lang3.text.StrBuilder);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendAll;;;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Iterable);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Iterator);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendAll;(Object[]);;ArrayElement of Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint",
@@ -249,14 +256,18 @@ private class ApacheStrBuilderModel extends SummaryModelCsv {
"org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendTo;;;Argument[-1];Argument[0];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[0..1];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Iterable,String);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Iterator,String);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;(Object[],String);;ArrayElement of Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint",
@@ -296,7 +307,8 @@ private class ApacheStrBuilderModel extends SummaryModelCsv {
"org.apache.commons.text;StrBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;append;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint",
@@ -305,7 +317,9 @@ private class ApacheStrBuilderModel extends SummaryModelCsv {
"org.apache.commons.text;StrBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;append;(org.apache.commons.text.StrBuilder);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;StrBuilder;false;appendAll;;;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendAll;(Iterable);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendAll;(Iterator);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendAll;(Object[]);;ArrayElement of Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint",
@@ -316,14 +330,18 @@ private class ApacheStrBuilderModel extends SummaryModelCsv {
"org.apache.commons.text;StrBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;StrBuilder;false;appendTo;;;Argument[-1];Argument[0];taint",
"org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[0..1];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Iterable,String);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Iterator,String);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendWithSeparators;(Object[],String);;ArrayElement of Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;StrBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StrBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint",
@@ -364,7 +382,8 @@ private class ApacheStrBuilderModel extends SummaryModelCsv {
"org.apache.commons.text;TextStringBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;append;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint",
@@ -373,7 +392,9 @@ private class ApacheStrBuilderModel extends SummaryModelCsv {
"org.apache.commons.text;TextStringBuilder;false;append;(java.nio.CharBuffer,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;append;(org.apache.commons.text.TextStringBuilder);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;append;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;TextStringBuilder;false;appendAll;;;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendAll;(Iterable);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendAll;(Iterator);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendAll;(Object[]);;ArrayElement of Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendAll;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[0];Argument[-1];taint",
@@ -384,14 +405,18 @@ private class ApacheStrBuilderModel extends SummaryModelCsv {
"org.apache.commons.text;TextStringBuilder;false;appendSeparator;(java.lang.String,java.lang.String);;Argument[0..1];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;TextStringBuilder;false;appendTo;;;Argument[-1];Argument[0];taint",
"org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[0..1];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Iterable,String);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Iterator,String);;Element of Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;(Object[],String);;ArrayElement of Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[1];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(char[]);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(char[],int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.Object);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0..1];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuffer);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuffer,int,int);;Argument[0];Argument[-1];taint",
"org.apache.commons.text;TextStringBuilder;false;appendln;(java.lang.StringBuilder);;Argument[0];Argument[-1];taint",
@@ -427,6 +452,101 @@ private class ApacheStrBuilderModel extends SummaryModelCsv {
}
}
private class ApacheStrBuilderFluentMethodsModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.lang3.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;appendNull;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;delete;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;reverse;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;setLength;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;setNullText;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.text;StrBuilder;false;trim;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;append;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;appendAll;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;appendln;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;appendNull;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;delete;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;insert;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;replace;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;reverse;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;setLength;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;setNullText;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;StrBuilder;false;trim;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;append;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;appendAll;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadLeft;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;appendFixedWidthPadRight;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;appendln;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;appendNewLine;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;appendNull;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;appendPadding;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;appendSeparator;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;appendWithSeparators;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;delete;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;deleteAll;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;deleteCharAt;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;deleteFirst;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;ensureCapacity;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;insert;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;minimizeCapacity;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;replace;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;replaceAll;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;replaceFirst;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;reverse;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;setCharAt;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;setLength;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;setNewLineText;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;setNullText;;;Argument[-1];ReturnValue;value",
"org.apache.commons.text;TextStringBuilder;false;trim;;;Argument[-1];ReturnValue;value"
]
}
}
/**
* An Apache Commons-Lang StrBuilder method that returns `this`.
*/
private class ApacheStrBuilderFluentMethod extends FluentMethod {
ApacheStrBuilderFluentMethod() {
this.getReturnType().(RefType).hasQualifiedName("org.apache.commons.lang3.text", "StrBuilder")
}
}
/**
* Taint-propagating models for `WordUtils`.
*/
@@ -525,9 +645,9 @@ private class ApacheStrLookupModel extends SummaryModelCsv {
row =
[
"org.apache.commons.lang3.text;StrLookup;false;lookup;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrLookup;false;mapLookup;;;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3.text;StrLookup;false;mapLookup;;;MapValue of Argument[0];ReturnValue;taint",
"org.apache.commons.text.lookup;StringLookup;true;lookup;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text.lookup;StringLookupFactory;false;mapStringLookup;;;Argument[0];ReturnValue;taint"
"org.apache.commons.text.lookup;StringLookupFactory;false;mapStringLookup;;;MapValue of Argument[0];ReturnValue;taint"
]
}
}
@@ -540,6 +660,7 @@ private class ApacheStrSubstitutorModel extends SummaryModelCsv {
row =
[
"org.apache.commons.lang3.text;StrSubstitutor;false;StrSubstitutor;;;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;StrSubstitutor;;;MapValue of Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(char[]);;Argument[0];ReturnValue;taint",
@@ -552,10 +673,12 @@ private class ApacheStrSubstitutorModel extends SummaryModelCsv {
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.StringBuffer,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.String,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(org.apache.commons.lang3.text.StrBuilder,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map);;MapValue of Argument[1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0..1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;MapValue of Argument[1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;MapValue of Argument[1];ReturnValue;taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;setVariableResolver;;;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(org.apache.commons.lang3.text.StrBuilder);;Argument[-1];Argument[0];taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuffer);;Argument[-1];Argument[0];taint",
@@ -564,6 +687,7 @@ private class ApacheStrSubstitutorModel extends SummaryModelCsv {
"org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(java.lang.StringBuilder,int,int);;Argument[-1];Argument[0];taint",
"org.apache.commons.lang3.text;StrSubstitutor;false;replaceIn;(org.apache.commons.lang3.text.StrBuilder,int,int);;Argument[-1];Argument[0];taint",
"org.apache.commons.text;StringSubstitutor;false;StringSubstitutor;;;Argument[0];Argument[-1];taint",
"org.apache.commons.text;StringSubstitutor;false;StringSubstitutor;;;MapValue of Argument[0];Argument[-1];taint",
"org.apache.commons.text;StringSubstitutor;false;replace;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object);;Argument[0];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(char[]);;Argument[0];ReturnValue;taint",
@@ -574,10 +698,12 @@ private class ApacheStrSubstitutorModel extends SummaryModelCsv {
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.StringBuffer);;Argument[0];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.StringBuffer,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.String,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0..1];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map);;Argument[0];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map);;MapValue of Argument[1];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[0];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;Argument[1];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0..1];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Map,java.lang.String,java.lang.String);;MapValue of Argument[1];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;Argument[0];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(java.lang.Object,java.util.Properties);;MapValue of Argument[1];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(org.apache.commons.text.TextStringBuilder);;Argument[0];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;replace;(org.apache.commons.text.TextStringBuilder,int,int);;Argument[0];ReturnValue;taint",
"org.apache.commons.text;StringSubstitutor;false;setVariableResolver;;;Argument[0];Argument[-1];taint",
@@ -637,3 +763,29 @@ private class ApacheObjectUtilsModel extends SummaryModelCsv {
]
}
}
private class ApacheToStringBuilderModel extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.lang3.builder;ToStringBuilder;false;toString;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.Object[]);;ArrayElement of Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,boolean);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object);;Argument[0..1];Argument[-1];taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;append;(java.lang.String,java.lang.Object[],boolean);;ArrayElement of Argument[1];Argument[-1];taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;build;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;getStringBuffer;;;Argument[-1];ReturnValue;taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[0];Argument[-1];taint",
"org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[0];Argument[-1];taint",
// The following are value-preserving steps for fluent methods:
"org.apache.commons.lang3.builder;ToStringBuilder;false;append;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.builder;ToStringBuilder;false;appendAsObjectToString;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.builder;ToStringBuilder;false;appendSuper;;;Argument[-1];ReturnValue;value",
"org.apache.commons.lang3.builder;ToStringBuilder;false;appendToString;;;Argument[-1];ReturnValue;value"
]
}
}

View File

@@ -22,21 +22,77 @@ private class GuavaBaseCsv extends SummaryModelCsv {
"com.google.common.base;Joiner;false;withKeyValueSeparator;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner;false;withKeyValueSeparator;(String);;Argument[-1];ReturnValue;taint",
"com.google.common.base;Joiner;false;withKeyValueSeparator;(char);;Argument[-1];ReturnValue;taint",
// Note: The signatures of some of the appendTo methods involve collection flow
"com.google.common.base;Joiner;false;appendTo;;;Argument[-1..3];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;(Appendable,Object,Object,Object[]);;Argument[1..2];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;(Appendable,Object,Object,Object[]);;ArrayElement of Argument[3];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;(Appendable,Iterable);;Element of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;(Appendable,Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;(Appendable,Iterator);;Element of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object,Object,Object[]);;Argument[1..2];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object,Object,Object[]);;ArrayElement of Argument[3];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;(StringBuilder,Iterable);;Element of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;(StringBuilder,Object[]);;ArrayElement of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;(StringBuilder,Iterator);;Element of Argument[1];Argument[-1];taint",
"com.google.common.base;Joiner;false;appendTo;;;Argument[-1];Argument[0];taint",
"com.google.common.base;Joiner;false;appendTo;;;Argument[0];ReturnValue;value",
"com.google.common.base;Joiner;false;join;;;Argument[-1..2];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;useForNull;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;useForNull;(String);;Argument[-1];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[1];Argument[0];taint",
"com.google.common.base;Joiner$MapJoiner;false;appendTo;;;Argument[0];ReturnValue;value",
"com.google.common.base;Joiner$MapJoiner;false;join;;;Argument[-1..0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;;;Argument[-1];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Iterable);;MapKey of Element of Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Iterable);;MapValue of Element of Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Iterator);;MapKey of Element of Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Iterator);;MapValue of Element of Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Map);;MapKey of Argument[0];ReturnValue;taint",
"com.google.common.base;Joiner$MapJoiner;false;join;(Map);;MapValue of Argument[0];ReturnValue;taint",
"com.google.common.base;Splitter;false;split;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Splitter;false;splitToList;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Splitter;false;splitToStream;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Splitter$MapSplitter;false;split;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Preconditions;false;checkNotNull;;;Argument[0];ReturnValue;value",
"com.google.common.base;MoreObjects;false;firstNonNull;;;Argument[0..1];ReturnValue;value"
"com.google.common.base;Verify;false;verifyNotNull;;;Argument[0];ReturnValue;value",
"com.google.common.base;Ascii;false;toLowerCase;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Ascii;false;toLowerCase;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Ascii;false;toUpperCase;(CharSequence);;Argument[0];ReturnValue;taint",
"com.google.common.base;Ascii;false;toUpperCase;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Ascii;false;truncate;(CharSequence,int,String);;Argument[0];ReturnValue;taint",
"com.google.common.base;Ascii;false;truncate;(CharSequence,int,String);;Argument[2];ReturnValue;taint",
"com.google.common.base;CaseFormat;true;to;(CaseFormat,String);;Argument[1];ReturnValue;taint",
"com.google.common.base;Converter;true;apply;(Object);;Argument[0];ReturnValue;taint",
"com.google.common.base;Converter;true;convert;(Object);;Argument[0];ReturnValue;taint",
"com.google.common.base;Converter;true;convertAll;(Iterable);;Element of Argument[0];Element of ReturnValue;taint",
"com.google.common.base;Supplier;true;get;();;Argument[0];ReturnValue;taint",
"com.google.common.base;Suppliers;false;ofInstance;(Object);;Argument[0];ReturnValue;taint",
"com.google.common.base;Suppliers;false;memoize;(Supplier);;Argument[0];ReturnValue;taint",
"com.google.common.base;Suppliers;false;memoizeWithExpiration;(Supplier,long,TimeUnit);;Argument[0];ReturnValue;taint",
"com.google.common.base;Suppliers;false;synchronizedSupplier;(Supplier);;Argument[0];ReturnValue;taint",
"com.google.common.base;Optional;true;fromJavaUtil;(Optional);;Element of Argument[0];Element of ReturnValue;value",
"com.google.common.base;Optional;true;fromNullable;(Object);;Argument[0];Element of ReturnValue;value",
"com.google.common.base;Optional;true;get;();;Element of Argument[-1];ReturnValue;value",
"com.google.common.base;Optional;true;asSet;();;Element of Argument[-1];Element of ReturnValue;value",
"com.google.common.base;Optional;true;of;(Object);;Argument[0];Element of ReturnValue;value",
"com.google.common.base;Optional;true;or;(Optional);;Element of Argument[-1..0];Element of ReturnValue;value",
"com.google.common.base;Optional;true;or;(Supplier);;Element of Argument[-1];ReturnValue;value",
"com.google.common.base;Optional;true;or;(Supplier);;Argument[0];ReturnValue;taint",
"com.google.common.base;Optional;true;or;(Object);;Element of Argument[-1];ReturnValue;value",
"com.google.common.base;Optional;true;or;(Object);;Argument[0];ReturnValue;value",
"com.google.common.base;Optional;true;orNull;();;Element of Argument[-1];ReturnValue;value",
"com.google.common.base;Optional;true;presentInstances;(Iterable);;Element of Element of Argument[0];Element of ReturnValue;value",
"com.google.common.base;Optional;true;toJavaUtil;();;Element of Argument[-1];Element of ReturnValue;value",
"com.google.common.base;Optional;true;toJavaUtil;(Optional);;Element of Argument[0];Element of ReturnValue;value",
"com.google.common.base;MoreObjects;false;firstNonNull;(Object,Object);;Argument[0..1];ReturnValue;value",
"com.google.common.base;MoreObjects;false;toStringHelper;(String);;Argument[0];ReturnValue;taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[0];ReturnValue;taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[0];Argument[-1];taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;add;;;Argument[-1];ReturnValue;value",
"com.google.common.base;MoreObjects$ToStringHelper;false;add;(String,Object);;Argument[1];ReturnValue;taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;add;(String,Object);;Argument[1];Argument[-1];taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;addValue;;;Argument[-1];ReturnValue;value",
"com.google.common.base;MoreObjects$ToStringHelper;false;addValue;(Object);;Argument[0];ReturnValue;taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;addValue;(Object);;Argument[0];Argument[-1];taint",
"com.google.common.base;MoreObjects$ToStringHelper;false;omitNullValues;();;Argument[-1];ReturnValue;value",
"com.google.common.base;MoreObjects$ToStringHelper;false;toString;();;Argument[-1];ReturnValue;taint"
]
}
}

View File

@@ -24,7 +24,9 @@ private class GuavaIoCsv extends SummaryModelCsv {
"com.google.common.io;BaseEncoding;true;omitPadding;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;BaseEncoding;true;encode;(byte[],int,int);;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteSource;true;asCharSource;(Charset);;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteSource;true;concat;;;Argument[0];ReturnValue;taint",
"com.google.common.io;ByteSource;true;concat;(ByteSource[]);;ArrayElement of Argument[0];ReturnValue;taint",
"com.google.common.io;ByteSource;true;concat;(Iterable);;Element of Argument[0];ReturnValue;taint",
"com.google.common.io;ByteSource;true;concat;(Iterator);;Element of Argument[0];ReturnValue;taint",
"com.google.common.io;ByteSource;true;copyTo;(OutputStream);;Argument[-1];Argument[0];taint",
"com.google.common.io;ByteSource;true;openStream;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;ByteSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint",
@@ -43,7 +45,9 @@ private class GuavaIoCsv extends SummaryModelCsv {
"com.google.common.io;ByteStreams;false;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint",
"com.google.common.io;ByteStreams;false;toByteArray;(InputStream);;Argument[0];ReturnValue;taint",
"com.google.common.io;CharSource;true;asByteSource;(Charset);;Argument[-1];ReturnValue;taint",
"com.google.common.io;CharSource;true;concat;;;Argument[0];ReturnValue;taint",
"com.google.common.io;CharSource;true;concat;(CharSource[]);;ArrayElement of Argument[0];ReturnValue;taint",
"com.google.common.io;CharSource;true;concat;(Iterable);;Element of Argument[0];ReturnValue;taint",
"com.google.common.io;CharSource;true;concat;(Iterator);;Element of Argument[0];ReturnValue;taint",
"com.google.common.io;CharSource;true;copyTo;(Appendable);;Argument[-1];Argument[0];taint",
"com.google.common.io;CharSource;true;openStream;();;Argument[-1];ReturnValue;taint",
"com.google.common.io;CharSource;true;openBufferedStream;();;Argument[-1];ReturnValue;taint",

View File

@@ -280,6 +280,7 @@ private class JacksonModel extends SummaryModelCsv {
row =
[
"com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;Argument[0];ReturnValue;taint",
"com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;MapValue of Argument[0];ReturnValue;taint",
"com.fasterxml.jackson.databind;ObjectMapper;true;convertValue;;;Argument[0];ReturnValue;taint"
]
}

View File

@@ -0,0 +1,27 @@
/** Provides classes to reason about System Information Leak vulnerabilities. */
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.security.XSS
/** CSV sink models representing methods not susceptible to XSS but outputing to an HTTP response body. */
private class DefaultInformationLeakSinkModel extends SinkModelCsv {
override predicate row(string row) {
row =
[
"javax.servlet.http;HttpServletResponse;false;sendError;(int,String);;Argument[1];information-leak"
]
}
}
/** A sink that represent a method that outputs data to an HTTP response. */
abstract class InformationLeakSink extends DataFlow::Node { }
/** A default sink representing methods outputing data to an HTTP response. */
private class DefaultInformationLeakSink extends InformationLeakSink {
DefaultInformationLeakSink() {
sinkNode(this, "information-leak") or
this instanceof XssSink
}
}

View File

@@ -0,0 +1,247 @@
/** Provides classes to reason about Expression Langauge (JEXL) injection vulnerabilities. */
import java
import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.dataflow.ExternalFlow
/**
* A sink for Expresssion Language injection vulnerabilities via Jexl,
* that is, method calls that run evaluation of a JEXL expression.
*/
abstract class JexlEvaluationSink extends DataFlow::ExprNode { }
/** Default sink for JXEL injection vulnerabilities. */
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.
*
* Extend this class to add additional taint steps that should apply to the `JexlInjectionFlowConfig`.
*/
class JexlInjectionAdditionalTaintStep extends Unit {
/**
* Holds if the step from `node1` to `node2` should be considered a taint
* step for the `JexlInjectionConfig` configuration.
*/
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
/** A set of additional taint steps to consider when taint tracking JXEL related data flows. */
private class DefaultJexlInjectionAdditionalTaintStep extends JexlInjectionAdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
createJexlScriptStep(node1, node2) or
createJexlExpressionStep(node1, node2) or
createJexlTemplateStep(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)`.
*/
private predicate createJexlScriptStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess ma, Method m | m = ma.getMethod() and n2.asExpr() = ma |
not isSafeEngine(ma.getQualifier()) and
m instanceof CreateJexlScriptMethod and
n1.asExpr() = ma.getArgument(0) and
n1.asExpr().getType() instanceof TypeString
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that creates a JEXL expression using an unsafe engine
* by calling `tainted.createExpression(jexlExpr)`.
*/
private predicate createJexlExpressionStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess ma, Method m | m = ma.getMethod() and n2.asExpr() = ma |
not isSafeEngine(ma.getQualifier()) and
m instanceof CreateJexlExpressionMethod and
n1.asExpr() = ma.getAnArgument() and
n1.asExpr().getType() instanceof TypeString
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that creates a JEXL template using an unsafe engine
* by calling `tainted.createTemplate(jexlExpr)`.
*/
private predicate createJexlTemplateStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess ma, Method m, RefType taintType |
m = ma.getMethod() and n2.asExpr() = ma and taintType = n1.asExpr().getType()
|
not isSafeEngine(ma.getQualifier()) and
m instanceof CreateJexlTemplateMethod and
n1.asExpr() = ma.getArgument([0, 1]) and
(taintType instanceof TypeString or taintType instanceof Reader)
)
}
/**
* Holds if `expr` is a JEXL engine that is configured with a sandbox.
*/
private predicate isSafeEngine(Expr expr) {
exists(SandboxedJexlFlowConfig config | config.hasFlowTo(DataFlow::exprNode(expr)))
}
/**
* A configuration for tracking sandboxed JEXL engines.
*/
private class SandboxedJexlFlowConfig extends DataFlow2::Configuration {
SandboxedJexlFlowConfig() { this = "JexlInjection::SandboxedJexlFlowConfig" }
override predicate isSource(DataFlow::Node node) { node instanceof SandboxedJexlSource }
override predicate isSink(DataFlow::Node node) {
exists(MethodAccess ma, Method m |
m instanceof CreateJexlScriptMethod or
m instanceof CreateJexlExpressionMethod or
m instanceof CreateJexlTemplateMethod
|
ma.getMethod() = m and ma.getQualifier() = node.asExpr()
)
}
override predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
createJexlEngineStep(fromNode, toNode)
}
}
/**
* Defines a data flow source for JEXL engines configured with a sandbox.
*/
private class SandboxedJexlSource extends DataFlow::ExprNode {
SandboxedJexlSource() {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
m.getDeclaringType() instanceof JexlBuilder and
m.hasName(["uberspect", "sandbox"]) and
m.getReturnType() instanceof JexlBuilder and
this.asExpr() = [ma, ma.getQualifier()]
)
or
exists(ConstructorCall cc |
cc.getConstructedType() instanceof JexlEngine and
cc.getArgument(0).getType() instanceof JexlUberspect and
cc = this.asExpr()
)
}
}
/**
* Holds if `fromNode` to `toNode` is a dataflow step that creates one of the JEXL engines.
*/
private predicate createJexlEngineStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
(m.getDeclaringType() instanceof JexlBuilder or m.getDeclaringType() instanceof JexlEngine) and
m.hasName(["create", "createJxltEngine"]) and
ma.getQualifier() = fromNode.asExpr() and
ma = toNode.asExpr()
)
or
exists(ConstructorCall cc |
cc.getConstructedType() instanceof UnifiedJexl and
cc.getArgument(0) = fromNode.asExpr() and
cc = toNode.asExpr()
)
}
/**
* A method that creates a JEXL script.
*/
private class CreateJexlScriptMethod extends Method {
CreateJexlScriptMethod() { getDeclaringType() instanceof JexlEngine and hasName("createScript") }
}
/**
* A method that creates a JEXL template.
*/
private class CreateJexlTemplateMethod extends Method {
CreateJexlTemplateMethod() {
(getDeclaringType() instanceof JxltEngine or getDeclaringType() instanceof UnifiedJexl) and
hasName("createTemplate")
}
}
/**
* A method that creates a JEXL expression.
*/
private class CreateJexlExpressionMethod extends Method {
CreateJexlExpressionMethod() {
(getDeclaringType() instanceof JexlEngine or getDeclaringType() instanceof JxltEngine) and
hasName("createExpression")
or
getDeclaringType() instanceof UnifiedJexl and hasName("parse")
}
}
private class JexlRefType extends RefType {
JexlRefType() { getPackage().hasName(["org.apache.commons.jexl2", "org.apache.commons.jexl3"]) }
}
private class JexlBuilder extends JexlRefType {
JexlBuilder() { hasName("JexlBuilder") }
}
private class JexlEngine extends JexlRefType {
JexlEngine() { hasName("JexlEngine") }
}
private class JxltEngine extends JexlRefType {
JxltEngine() { hasName("JxltEngine") }
}
private class UnifiedJexl extends JexlRefType {
UnifiedJexl() { hasName("UnifiedJEXL") }
}
private class JexlUberspect extends Interface {
JexlUberspect() {
hasQualifiedName("org.apache.commons.jexl2.introspection", "Uberspect") or
hasQualifiedName("org.apache.commons.jexl3.introspection", "JexlUberspect")
}
}
private class Reader extends RefType {
Reader() { hasQualifiedName("java.io", "Reader") }
}

View File

@@ -34,7 +34,6 @@ private class DefaultXssSinkModel extends SinkModelCsv {
override predicate row(string row) {
row =
[
"javax.servlet.http;HttpServletResponse;false;sendError;(int,String);;Argument[1];xss",
"android.webkit;WebView;false;loadData;;;Argument[0];xss",
"android.webkit;WebView;false;loadUrl;;;Argument[0];xss",
"android.webkit;WebView;false;loadDataWithBaseURL;;;Argument[1];xss"