Skip to content

Commit 7c0e89f

Browse files
committed
Java: Refactor ArithmeticTainted.ql, TempDirLocalInformationDisclosure.ql
1 parent da27326 commit 7c0e89f

File tree

2 files changed

+60
-47
lines changed

2 files changed

+60
-47
lines changed

java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,39 @@
1515
import java
1616
import semmle.code.java.dataflow.FlowSources
1717
import ArithmeticCommon
18-
import DataFlow::PathGraph
1918

20-
class RemoteUserInputOverflowConfig extends TaintTracking::Configuration {
21-
RemoteUserInputOverflowConfig() { this = "ArithmeticTainted.ql:RemoteUserInputOverflowConfig" }
19+
module RemoteUserInputOverflowConfig implements DataFlow::ConfigSig {
20+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
2221

23-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
22+
predicate isSink(DataFlow::Node sink) { overflowSink(_, sink.asExpr()) }
2423

25-
override predicate isSink(DataFlow::Node sink) { overflowSink(_, sink.asExpr()) }
24+
predicate isBarrier(DataFlow::Node n) { overflowBarrier(n) }
25+
}
26+
27+
module RemoteUserInputUnderflowConfig implements DataFlow::ConfigSig {
28+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
2629

27-
override predicate isSanitizer(DataFlow::Node n) { overflowBarrier(n) }
30+
predicate isSink(DataFlow::Node sink) { underflowSink(_, sink.asExpr()) }
31+
32+
predicate isBarrier(DataFlow::Node n) { underflowBarrier(n) }
2833
}
2934

30-
class RemoteUserInputUnderflowConfig extends TaintTracking::Configuration {
31-
RemoteUserInputUnderflowConfig() { this = "ArithmeticTainted.ql:RemoteUserInputUnderflowConfig" }
35+
module RemoteUserInputOverflow = TaintTracking::Make<RemoteUserInputOverflowConfig>;
3236

33-
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
37+
module RemoteUserInputUnderflow = TaintTracking::Make<RemoteUserInputUnderflowConfig>;
3438

35-
override predicate isSink(DataFlow::Node sink) { underflowSink(_, sink.asExpr()) }
39+
module Flow =
40+
DataFlow::MergePathGraph<RemoteUserInputOverflow::PathNode, RemoteUserInputUnderflow::PathNode, RemoteUserInputOverflow::PathGraph, RemoteUserInputUnderflow::PathGraph>;
3641

37-
override predicate isSanitizer(DataFlow::Node n) { underflowBarrier(n) }
38-
}
42+
import Flow::PathGraph
3943

40-
from DataFlow::PathNode source, DataFlow::PathNode sink, ArithExpr exp, string effect
44+
from Flow::PathNode source, Flow::PathNode sink, ArithExpr exp, string effect
4145
where
42-
any(RemoteUserInputOverflowConfig c).hasFlowPath(source, sink) and
46+
RemoteUserInputOverflow::hasFlowPath(source.asPathNode1(), sink.asPathNode1()) and
4347
overflowSink(exp, sink.getNode().asExpr()) and
4448
effect = "overflow"
4549
or
46-
any(RemoteUserInputUnderflowConfig c).hasFlowPath(source, sink) and
50+
RemoteUserInputUnderflow::hasFlowPath(source.asPathNode2(), sink.asPathNode2()) and
4751
underflowSink(exp, sink.getNode().asExpr()) and
4852
effect = "underflow"
4953
select exp, source, sink,

java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
import java
1515
import semmle.code.java.os.OSCheck
1616
import TempDirUtils
17-
import DataFlow::PathGraph
18-
import semmle.code.java.dataflow.TaintTracking2
17+
import semmle.code.java.dataflow.TaintTracking
1918

2019
abstract private class MethodFileSystemFileCreation extends Method {
2120
MethodFileSystemFileCreation() { this.getDeclaringType() instanceof TypeFile }
@@ -127,19 +126,17 @@ private class IsSpecificWindowsSanitizer extends WindowsOsSanitizer {
127126
* A taint tracking configuration tracking the access of the system temporary directory
128127
* flowing to the creation of files or directories.
129128
*/
130-
private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Configuration {
131-
TempDirSystemGetPropertyToCreateConfig() { this = "TempDirSystemGetPropertyToCreateConfig" }
132-
133-
override predicate isSource(DataFlow::Node source) {
129+
module TempDirSystemGetPropertyToCreateConfig implements DataFlow::ConfigSig {
130+
predicate isSource(DataFlow::Node source) {
134131
source.asExpr() instanceof ExprSystemGetPropertyTempDirTainted
135132
}
136133

137-
override predicate isSink(DataFlow::Node sink) {
134+
predicate isSink(DataFlow::Node sink) {
138135
sink instanceof FileCreationSink and
139-
not any(TempDirSystemGetPropertyDirectlyToMkdirConfig config).hasFlowTo(sink)
136+
not TempDirSystemGetPropertyDirectlyToMkdir::hasFlowTo(sink)
140137
}
141138

142-
override predicate isSanitizer(DataFlow::Node sanitizer) {
139+
predicate isBarrier(DataFlow::Node sanitizer) {
143140
exists(FilesSanitizingCreationMethodAccess sanitisingMethodAccess |
144141
sanitizer.asExpr() = sanitisingMethodAccess.getArgument(0)
145142
)
@@ -148,6 +145,9 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
148145
}
149146
}
150147

148+
module TempDirSystemGetPropertyToCreate =
149+
TaintTracking::Make<TempDirSystemGetPropertyToCreateConfig>;
150+
151151
/**
152152
* Configuration that tracks calls to to `mkdir` or `mkdirs` that are are directly on the temp directory system property.
153153
* Examples:
@@ -158,30 +158,29 @@ private class TempDirSystemGetPropertyToCreateConfig extends TaintTracking::Conf
158158
* As such, this code pattern is filtered out as an explicit vulnerability in
159159
* `TempDirSystemGetPropertyToCreateConfig::isSink`.
160160
*/
161-
private class TempDirSystemGetPropertyDirectlyToMkdirConfig extends TaintTracking2::Configuration {
162-
TempDirSystemGetPropertyDirectlyToMkdirConfig() {
163-
this = "TempDirSystemGetPropertyDirectlyToMkdirConfig"
164-
}
165-
166-
override predicate isSource(DataFlow::Node node) {
161+
module TempDirSystemGetPropertyDirectlyToMkdirConfig implements DataFlow::ConfigSig {
162+
predicate isSource(DataFlow::Node node) {
167163
exists(ExprSystemGetPropertyTempDirTainted propertyGetExpr, DataFlow::Node callSite |
168164
DataFlow::localFlow(DataFlow::exprNode(propertyGetExpr), callSite)
169165
|
170166
isFileConstructorArgument(callSite.asExpr(), node.asExpr(), 1)
171167
)
172168
}
173169

174-
override predicate isSink(DataFlow::Node node) {
170+
predicate isSink(DataFlow::Node node) {
175171
exists(MethodAccess ma | ma.getMethod() instanceof MethodFileDirectoryCreation |
176172
ma.getQualifier() = node.asExpr()
177173
)
178174
}
179175

180-
override predicate isSanitizer(DataFlow::Node sanitizer) {
176+
predicate isBarrier(DataFlow::Node sanitizer) {
181177
isFileConstructorArgument(sanitizer.asExpr(), _, _)
182178
}
183179
}
184180

181+
module TempDirSystemGetPropertyDirectlyToMkdir =
182+
TaintTracking::Make<TempDirSystemGetPropertyDirectlyToMkdirConfig>;
183+
185184
//
186185
// Begin configuration for tracking single-method calls that are vulnerable.
187186
//
@@ -193,6 +192,8 @@ abstract class MethodAccessInsecureFileCreation extends MethodAccess {
193192
* Gets the type of entity created (e.g. `file`, `directory`, ...).
194193
*/
195194
abstract string getFileSystemEntityType();
195+
196+
DataFlow::Node getNode() { result.asExpr() = this }
196197
}
197198

198199
/**
@@ -235,39 +236,47 @@ class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureF
235236
}
236237

237238
/**
238-
* A hack: we include use of inherently insecure methods, which don't have any associated
239+
* We include use of inherently insecure methods, which don't have any associated
239240
* flow path, in with results describing a path from reading `java.io.tmpdir` or similar to use
240241
* in a file creation op.
241242
*
242-
* We achieve this by making inherently-insecure method invocations both a source and a sink in
243-
* this configuration, resulting in a zero-length path which is type-compatible with the actual
244-
* path-flow results.
243+
* We achieve this by making inherently-insecure method invocations into an edge-less graph,
244+
* resulting in a zero-length paths.
245245
*/
246-
class InsecureMethodPseudoConfiguration extends DataFlow::Configuration {
247-
InsecureMethodPseudoConfiguration() { this = "InsecureMethodPseudoConfiguration" }
246+
module InsecureMethodPathGraph implements DataFlow::PathGraphSig<MethodAccessInsecureFileCreation> {
247+
predicate edges(MethodAccessInsecureFileCreation n1, MethodAccessInsecureFileCreation n2) {
248+
none()
249+
}
248250

249-
override predicate isSource(DataFlow::Node node) {
250-
node.asExpr() instanceof MethodAccessInsecureFileCreation
251+
predicate nodes(MethodAccessInsecureFileCreation n, string key, string val) {
252+
key = "semmle.label" and val = n.toString()
251253
}
252254

253-
override predicate isSink(DataFlow::Node node) {
254-
node.asExpr() instanceof MethodAccessInsecureFileCreation
255+
predicate subpaths(
256+
MethodAccessInsecureFileCreation n1, MethodAccessInsecureFileCreation n2,
257+
MethodAccessInsecureFileCreation n3, MethodAccessInsecureFileCreation n4
258+
) {
259+
none()
255260
}
256261
}
257262

258-
from DataFlow::PathNode source, DataFlow::PathNode sink, string message
263+
module Flow =
264+
DataFlow::MergePathGraph<TempDirSystemGetPropertyToCreate::PathNode, MethodAccessInsecureFileCreation, TempDirSystemGetPropertyToCreate::PathGraph, InsecureMethodPathGraph>;
265+
266+
import Flow::PathGraph
267+
268+
from Flow::PathNode source, Flow::PathNode sink, string message
259269
where
260270
(
261-
any(TempDirSystemGetPropertyToCreateConfig conf).hasFlowPath(source, sink) and
271+
TempDirSystemGetPropertyToCreate::hasFlowPath(source.asPathNode1(), sink.asPathNode1()) and
262272
message =
263273
"Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users."
264274
or
265-
any(InsecureMethodPseudoConfiguration conf).hasFlowPath(source, sink) and
275+
source = sink and
266276
// Note this message has no "$@" placeholder, so the "system temp directory" template parameter below is not used.
267277
message =
268278
"Local information disclosure vulnerability due to use of " +
269-
source.getNode().asExpr().(MethodAccessInsecureFileCreation).getFileSystemEntityType() +
270-
" readable by other local users."
279+
source.asPathNode2().getFileSystemEntityType() + " readable by other local users."
271280
) and
272281
not isPermissionsProtectedTempDirUse(sink.getNode())
273282
select source.getNode(), source, sink, message, source.getNode(), "system temp directory"

0 commit comments

Comments
 (0)