Skip to content

Commit f431089

Browse files
author
Benjamin Muskalla
committed
Capture sources flowing into parameters
1 parent 8040d9c commit f431089

File tree

5 files changed

+60
-34
lines changed

5 files changed

+60
-34
lines changed

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ private import ModelGeneratorUtils
1313
private import semmle.code.java.dataflow.internal.FlowSummaryImplSpecific
1414
private import semmle.code.java.dataflow.internal.FlowSummaryImpl
1515
private import semmle.code.java.dataflow.internal.DataFlowImplCommon
16+
private import semmle.code.java.dataflow.internal.DataFlowPrivate
1617
private import semmle.code.java.dataflow.internal.DataFlowNodes::Private
1718

1819
class FromSourceConfiguration extends TaintTracking::Configuration {
@@ -22,7 +23,7 @@ class FromSourceConfiguration extends TaintTracking::Configuration {
2223

2324
override predicate isSink(DataFlow::Node sink) {
2425
exists(TargetAPI c |
25-
sink instanceof ReturnNode and
26+
sink instanceof ReturnNodeExt and
2627
sink.getEnclosingCallable() = c and
2728
c.isPublic() and
2829
c.fromSource()
@@ -32,14 +33,30 @@ class FromSourceConfiguration extends TaintTracking::Configuration {
3233
override DataFlow::FlowFeature getAFeature() {
3334
result instanceof DataFlow::FeatureHasSinkCallContext
3435
}
36+
37+
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
38+
exists(DataFlow::Content f |
39+
readStep(node1, f, node2) and
40+
if f instanceof DataFlow::FieldContent
41+
then isRelevantType(f.(DataFlow::FieldContent).getField().getType())
42+
else any()
43+
)
44+
or
45+
exists(DataFlow::Content f | storeStep(node1, f, node2) |
46+
f instanceof DataFlow::ArrayContent or
47+
f instanceof DataFlow::CollectionContent or
48+
f instanceof DataFlow::MapKeyContent or
49+
f instanceof DataFlow::MapValueContent
50+
)
51+
}
3552
}
3653

3754
string captureSource(TargetAPI api) {
3855
exists(DataFlow::Node source, DataFlow::Node sink, FromSourceConfiguration config, string kind |
3956
config.hasFlow(source, sink) and
4057
sourceNode(source, kind) and
4158
api = source.getEnclosingCallable() and
42-
result = asSourceModel(api, "ReturnValue", kind)
59+
result = asSourceModel(api, returnNodeAsOutput(api, sink), kind)
4360
)
4461
}
4562

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

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,10 @@ string captureFieldFlow(TargetAPI api) {
103103
not api.getDeclaringType() instanceof EnumType and
104104
isRelevantType(returnNodeExt.getType())
105105
|
106-
result = asTaintModel(api, "Argument[-1]", asOutput(api, returnNodeExt))
106+
result = asTaintModel(api, "Argument[-1]", returnNodeAsOutput(api, returnNodeExt))
107107
)
108108
}
109109

110-
string asOutput(TargetAPI api, ReturnNodeExt node) {
111-
if node.getKind() instanceof ValueReturnKind
112-
then result = "ReturnValue"
113-
else
114-
result = parameterAccess(api.getParameter(node.getKind().(ParamUpdateReturnKind).getPosition()))
115-
}
116-
117110
class FieldAssignment extends AssignExpr {
118111
FieldAssignment() { exists(Field f | f.getAnAccess() = this.getDest()) }
119112
}
@@ -166,7 +159,6 @@ private predicate thisAccess(DataFlow::Node n) {
166159
*/
167160
string captureFieldFlowIn(TargetAPI api) {
168161
exists(DataFlow::Node source, ParameterToFieldConfig config |
169-
not api.isStatic() and
170162
config.hasFlow(source, _) and
171163
source.asParameter().getCallable() = api
172164
|
@@ -257,27 +249,6 @@ string captureParameterToParameterFlow(TargetAPI api) {
257249
)
258250
}
259251

260-
predicate isRelevantType(Type t) {
261-
not t instanceof TypeClass and
262-
not t instanceof EnumType and
263-
not t instanceof PrimitiveType and
264-
not t instanceof BoxedType and
265-
not t.(RefType).getAnAncestor().hasQualifiedName("java.lang", "Number") and
266-
not t.(RefType).getAnAncestor().hasQualifiedName("java.nio.charset", "Charset") and
267-
(
268-
not t.(Array).getElementType() instanceof PrimitiveType or
269-
isPrimitiveTypeUsedForBulkData(t.(Array).getElementType())
270-
) and
271-
(
272-
not t.(Array).getElementType() instanceof BoxedType or
273-
isPrimitiveTypeUsedForBulkData(t.(Array).getElementType())
274-
) and
275-
(
276-
not t.(CollectionType).getElementType() instanceof BoxedType or
277-
isPrimitiveTypeUsedForBulkData(t.(CollectionType).getElementType())
278-
)
279-
}
280-
281252
from TargetAPI api, string flow
282253
where flow = captureFlow(api)
283254
select flow order by flow

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import java
2-
import semmle.code.java.dataflow.ExternalFlow
3-
import semmle.code.java.dataflow.internal.ContainerFlow
2+
private import semmle.code.java.dataflow.ExternalFlow
3+
private import semmle.code.java.dataflow.internal.ContainerFlow
4+
private import semmle.code.java.dataflow.internal.DataFlowImplCommon
45

56
Method superImpl(Method m) {
67
result = m.getAnOverride() and
@@ -110,6 +111,34 @@ private string typeAsModel(RefType type) {
110111
result = type.getCompilationUnit().getPackage().getName() + ";" + type.nestedName()
111112
}
112113

114+
predicate isRelevantType(Type t) {
115+
not t instanceof TypeClass and
116+
not t instanceof EnumType and
117+
not t instanceof PrimitiveType and
118+
not t instanceof BoxedType and
119+
not t.(RefType).getAnAncestor().hasQualifiedName("java.lang", "Number") and
120+
not t.(RefType).getAnAncestor().hasQualifiedName("java.nio.charset", "Charset") and
121+
(
122+
not t.(Array).getElementType() instanceof PrimitiveType or
123+
isPrimitiveTypeUsedForBulkData(t.(Array).getElementType())
124+
) and
125+
(
126+
not t.(Array).getElementType() instanceof BoxedType or
127+
isPrimitiveTypeUsedForBulkData(t.(Array).getElementType())
128+
) and
129+
(
130+
not t.(CollectionType).getElementType() instanceof BoxedType or
131+
isPrimitiveTypeUsedForBulkData(t.(CollectionType).getElementType())
132+
)
133+
}
134+
135+
string returnNodeAsOutput(TargetAPI api, ReturnNodeExt node) {
136+
if node.getKind() instanceof ValueReturnKind
137+
then result = "ReturnValue"
138+
else
139+
result = parameterAccess(api.getParameter(node.getKind().(ParamUpdateReturnKind).getPosition()))
140+
}
141+
113142
string parameterAccess(Parameter p) {
114143
if
115144
p.getType() instanceof Array and
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
| p;Sources;true;readUrl;(URL);;ReturnValue;remote |
22
| p;Sources;true;socketStream;();;ReturnValue;remote |
3+
| p;Sources;true;sourceToParameter;(InputStream[],List);;ArrayElement of Argument[0];remote |
4+
| p;Sources;true;sourceToParameter;(InputStream[],List);;Element of Argument[1];remote |

java/ql/test/utils/model-generator/p/Sources.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.net.ServerSocket;
66
import java.net.URL;
77
import java.util.function.Consumer;
8+
import java.util.List;
89

910

1011
public class Sources {
@@ -18,4 +19,10 @@ public InputStream socketStream() throws IOException {
1819
return socket.accept().getInputStream();
1920
}
2021

22+
public void sourceToParameter(InputStream[] streams, List<InputStream> otherStreams) throws IOException {
23+
ServerSocket socket = new ServerSocket(123);
24+
streams[0] = socket.accept().getInputStream();
25+
otherStreams.add(socket.accept().getInputStream());
26+
}
27+
2128
}

0 commit comments

Comments
 (0)