Capture argument->return value flows

This commit is contained in:
Benjamin Muskalla
2021-09-24 15:43:43 +02:00
parent 4ca006ba3d
commit c3462be2c9
4 changed files with 122 additions and 1 deletions

View File

@@ -6,8 +6,13 @@
import java
import ModelGeneratorUtils
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.internal.DataFlowImplCommon
string captureFlow(Callable api) { result = captureQualifierFlow(api) }
string captureFlow(Callable api) {
result = captureQualifierFlow(api) or
result = captureParameterFlowToReturnValue(api)
}
string captureQualifierFlow(Callable api) {
exists(ReturnStmt rtn |
@@ -17,6 +22,44 @@ string captureQualifierFlow(Callable api) {
result = asValueModel(api, "Argument[-1]", "ReturnValue")
}
class ParameterToReturnValueTaintConfig extends TaintTracking::Configuration {
ParameterToReturnValueTaintConfig() { this = "ParameterToReturnValueTaintConfig" }
override predicate isSource(DataFlow::Node source) {
exists(Parameter p, Callable api |
p = source.asParameter() and
api = p.getCallable() and
(
not api.getReturnType() instanceof PrimitiveType and
not p.getType() instanceof PrimitiveType
) and
(
not api.getReturnType() instanceof TypeClass and
not p.getType() instanceof TypeClass
)
)
}
override predicate isSink(DataFlow::Node sink) { sink instanceof ReturnNodeExt }
}
// TODO: rtn -> Node as ReturnNodeExt is also PostUpdateNode, might be able to merge with p2p flow
predicate paramFlowToReturnValueExists(Parameter p) {
exists(ParameterToReturnValueTaintConfig config, ReturnStmt rtn |
rtn.getEnclosingCallable() = p.getCallable() and
config.hasFlow(DataFlow::parameterNode(p), DataFlow::exprNode(rtn.getResult()))
)
}
string captureParameterFlowToReturnValue(Callable api) {
exists(Parameter p |
p = api.getAParameter() and
paramFlowToReturnValueExists(p)
|
result = asTaintModel(api, parameterAccess(p), "ReturnValue")
)
}
// TODO: handle cases like Ticker
// TODO: "com.google.common.base;Converter;true;convertAll;(Iterable);;Element of Argument[0];Element of ReturnValue;taint",
// TODO: infer interface from multiple implementations? e.g. UriComponentsContributor

View File

@@ -1,5 +1,6 @@
import java
import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.dataflow.internal.ContainerFlow
string isExtensible(RefType ref) { if ref.isFinal() then result = "false" else result = "true" }
@@ -26,3 +27,12 @@ string asSummaryModel(Callable api, string input, string output, string kind) {
+ output + ";" //
+ kind + ";" //
}
string parameterAccess(Parameter p) {
if p.getType() instanceof Array
then result = "ArrayElement of Argument[" + p.getPosition() + "]"
else
if p.getType() instanceof ContainerType
then result = "Element of Argument[" + p.getPosition() + "]"
else result = "Argument[" + p.getPosition() + "]"
}