Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c3462be

Browse files
author
Benjamin Muskalla
committed
Capture argument->return value flows
1 parent 4ca006b commit c3462be

4 files changed

Lines changed: 122 additions & 1 deletion

File tree

java/ql/src/utils/model-generator/CaptureSummaryModels.ql

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66

77
import java
88
import ModelGeneratorUtils
9+
import semmle.code.java.dataflow.TaintTracking
10+
import semmle.code.java.dataflow.internal.DataFlowImplCommon
911

10-
string captureFlow(Callable api) { result = captureQualifierFlow(api) }
12+
string captureFlow(Callable api) {
13+
result = captureQualifierFlow(api) or
14+
result = captureParameterFlowToReturnValue(api)
15+
}
1116

1217
string captureQualifierFlow(Callable api) {
1318
exists(ReturnStmt rtn |
@@ -17,6 +22,44 @@ string captureQualifierFlow(Callable api) {
1722
result = asValueModel(api, "Argument[-1]", "ReturnValue")
1823
}
1924

25+
class ParameterToReturnValueTaintConfig extends TaintTracking::Configuration {
26+
ParameterToReturnValueTaintConfig() { this = "ParameterToReturnValueTaintConfig" }
27+
28+
override predicate isSource(DataFlow::Node source) {
29+
exists(Parameter p, Callable api |
30+
p = source.asParameter() and
31+
api = p.getCallable() and
32+
(
33+
not api.getReturnType() instanceof PrimitiveType and
34+
not p.getType() instanceof PrimitiveType
35+
) and
36+
(
37+
not api.getReturnType() instanceof TypeClass and
38+
not p.getType() instanceof TypeClass
39+
)
40+
)
41+
}
42+
43+
override predicate isSink(DataFlow::Node sink) { sink instanceof ReturnNodeExt }
44+
}
45+
46+
// TODO: rtn -> Node as ReturnNodeExt is also PostUpdateNode, might be able to merge with p2p flow
47+
predicate paramFlowToReturnValueExists(Parameter p) {
48+
exists(ParameterToReturnValueTaintConfig config, ReturnStmt rtn |
49+
rtn.getEnclosingCallable() = p.getCallable() and
50+
config.hasFlow(DataFlow::parameterNode(p), DataFlow::exprNode(rtn.getResult()))
51+
)
52+
}
53+
54+
string captureParameterFlowToReturnValue(Callable api) {
55+
exists(Parameter p |
56+
p = api.getAParameter() and
57+
paramFlowToReturnValueExists(p)
58+
|
59+
result = asTaintModel(api, parameterAccess(p), "ReturnValue")
60+
)
61+
}
62+
2063
// TODO: handle cases like Ticker
2164
// TODO: "com.google.common.base;Converter;true;convertAll;(Iterable);;Element of Argument[0];Element of ReturnValue;taint",
2265
// TODO: infer interface from multiple implementations? e.g. UriComponentsContributor

java/ql/src/utils/model-generator/ModelGeneratorUtils.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import java
22
import semmle.code.java.dataflow.ExternalFlow
3+
import semmle.code.java.dataflow.internal.ContainerFlow
34

45
string isExtensible(RefType ref) { if ref.isFinal() then result = "false" else result = "true" }
56

@@ -26,3 +27,12 @@ string asSummaryModel(Callable api, string input, string output, string kind) {
2627
+ output + ";" //
2728
+ kind + ";" //
2829
}
30+
31+
string parameterAccess(Parameter p) {
32+
if p.getType() instanceof Array
33+
then result = "ArrayElement of Argument[" + p.getPosition() + "]"
34+
else
35+
if p.getType() instanceof ContainerType
36+
then result = "Element of Argument[" + p.getPosition() + "]"
37+
else result = "Argument[" + p.getPosition() + "]"
38+
}

java/ql/test/utils/model-generator/CaptureSummaryModels.expected

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,12 @@
22
| p;FluentAPI;false;returnsThis;(String);;Argument[-1];ReturnValue;value; |
33
| p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint; |
44
| p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint; |
5+
| p;ParamFlow;true;addTo;(String,List);;Argument[0];Element of Argument[1];taint; |
6+
| p;ParamFlow;true;returnArrayElement;(String[]);;ArrayElement of Argument[0];ReturnValue;taint; |
7+
| p;ParamFlow;true;returnCollectionElement;(List);;Element of Argument[0];ReturnValue;taint; |
8+
| p;ParamFlow;true;returnIterableElement;(Iterable);;Element of Argument[0];ReturnValue;taint; |
9+
| p;ParamFlow;true;returnIteratorElement;(Iterator);;Element of Argument[0];ReturnValue;taint; |
10+
| p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint; |
11+
| p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint; |
12+
| p;ParamFlow;true;returnVarArgElement;(String[]);;ArrayElement of Argument[0];ReturnValue;taint; |
13+
| p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint; |
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package p;
2+
3+
import java.util.Iterator;
4+
import java.util.List;
5+
import java.io.IOException;
6+
import java.io.OutputStream;
7+
8+
9+
public class ParamFlow {
10+
11+
public String returnsInput(String input) {
12+
return input;
13+
}
14+
15+
public int ignorePrimitiveReturnValue(String input) {
16+
return input.length();
17+
}
18+
19+
public String returnMultipleParameters(String one, String two) {
20+
if (System.currentTimeMillis() > 100) {
21+
return two;
22+
}
23+
return one;
24+
}
25+
26+
public String returnArrayElement(String[] input) {
27+
return input[0];
28+
}
29+
30+
public String returnVarArgElement(String... input) {
31+
return input[0];
32+
}
33+
34+
public String returnCollectionElement(List<String> input) {
35+
return input.get(0);
36+
}
37+
38+
public String returnIteratorElement(Iterator<String> input) {
39+
return input.next();
40+
}
41+
42+
public String returnIterableElement(Iterable<String> input) {
43+
return input.iterator().next();
44+
}
45+
46+
public Class<?> mapType(Class<?> input) {
47+
return input;
48+
}
49+
50+
public void writeChunked(byte[] data, OutputStream output)
51+
throws IOException {
52+
output.write(data, 0, data.length);
53+
}
54+
55+
public void addTo(String data, List<String> target) {
56+
target.add(data);
57+
}
58+
59+
}

0 commit comments

Comments
 (0)