-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathTaintedPath.ql
More file actions
70 lines (62 loc) · 2.36 KB
/
TaintedPath.ql
File metadata and controls
70 lines (62 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
* @name Uncontrolled data used in path expression
* @description Accessing paths influenced by users can allow an attacker to access unexpected resources.
* @kind path-problem
* @problem.severity error
* @security-severity 7.5
* @precision high
* @id java/path-injection
* @tags security
* external/cwe/cwe-022
* external/cwe/cwe-023
* external/cwe/cwe-036
* external/cwe/cwe-073
*/
import java
import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.security.PathCreation
import DataFlow::PathGraph
import TaintedPathCommon
predicate containsDotDotSanitizer(Guard g, Expr e, boolean branch) {
exists(MethodAccess contains | g = contains |
contains.getMethod().hasName("contains") and
contains.getAnArgument().(StringLiteral).getValue() = ".." and
e = contains.getQualifier() and
branch = false
)
}
class TaintedPathConfig extends TaintTracking::Configuration {
TaintedPathConfig() { this = "TaintedPathConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
(
sink.asExpr() = any(PathCreation p).getAnInput()
or
sinkNode(sink, "create-file")
) and
not guarded(sink.asExpr())
}
override predicate isSanitizer(DataFlow::Node node) {
exists(Type t | t = node.getType() | t instanceof BoxedType or t instanceof PrimitiveType)
or
node = DataFlow::BarrierGuard<containsDotDotSanitizer/3>::getABarrierNode()
}
}
/**
* Gets the data-flow node at which to report a path ending at `sink`.
*
* Previously this query flagged alerts exclusively at `PathCreation` sites,
* so to avoid perturbing existing alerts, where a `PathCreation` exists we
* continue to report there; otherwise we report directly at `sink`.
*/
DataFlow::Node getReportingNode(DataFlow::Node sink) {
any(TaintedPathConfig c).hasFlowTo(sink) and
if exists(PathCreation pc | pc.getAnInput() = sink.asExpr())
then result.asExpr() = any(PathCreation pc | pc.getAnInput() = sink.asExpr())
else result = sink
}
from DataFlow::PathNode source, DataFlow::PathNode sink, TaintedPathConfig conf
where conf.hasFlowPath(source, sink)
select getReportingNode(sink.getNode()), source, sink, "$@ flows to here and is used in a path.",
source.getNode(), "User-provided value"