mirror of
https://github.com/github/codeql.git
synced 2026-03-05 15:16:47 +01:00
Capture argument->return value flows
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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() + "]"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user