forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSanitizers.qll
More file actions
76 lines (71 loc) · 2.87 KB
/
Sanitizers.qll
File metadata and controls
76 lines (71 loc) · 2.87 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
71
72
73
74
75
76
/** Classes to represent sanitizers commonly used in dataflow and taint tracking configurations. */
overlay[local?]
module;
import java
private import semmle.code.java.controlflow.Guards
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.frameworks.Regex
/**
* A node whose type is a simple type unlikely to carry taint, such as primitives and their boxed counterparts,
* `java.util.UUID` and `java.util.Date`.
*/
class SimpleTypeSanitizer extends DataFlow::Node {
SimpleTypeSanitizer() {
this.getType() instanceof PrimitiveType or
this.getType() instanceof BoxedType or
this.getType() instanceof NumberType or
this.getType().(RefType).hasQualifiedName("java.util", "UUID") or
this.getType().(RefType).getASourceSupertype*().hasQualifiedName("java.util", "Date") or
this.getType().(RefType).hasQualifiedName("java.util", "Calendar") or
this.getType().(RefType).hasQualifiedName("java.util", "BitSet") or
this.getType()
.(RefType)
.getASourceSupertype*()
.hasQualifiedName("java.time.temporal", "TemporalAmount") or
this.getType()
.(RefType)
.getASourceSupertype*()
.hasQualifiedName("java.time.temporal", "TemporalAccessor") or
this.getType() instanceof EnumType
}
}
/**
* Holds if `guard` holds with branch `branch` if `e` matches a regular expression.
*
* This is overapproximate: we do not attempt to reason about the correctness of the regexp.
*
* Use this if you want to define a derived `DataFlow::BarrierGuard` without
* make the type recursive. Otherwise use `RegexpCheckBarrier`.
*/
predicate regexpMatchGuardChecks(Guard guard, Expr e, boolean branch) {
exists(RegexMatch rm | not rm instanceof Annotation |
guard = rm and
e = rm.getASanitizedExpr() and
branch = true
)
}
/**
* A check against a regular expression, considered as a barrier guard.
*
* This is overapproximate: we do not attempt to reason about the correctness of the regexp.
*/
class RegexpCheckBarrier extends DataFlow::Node {
RegexpCheckBarrier() {
this = DataFlow::BarrierGuard<regexpMatchGuardChecks/3>::getABarrierNode()
or
// Annotations don't fit into the model of barrier guards because the
// annotation doesn't dominate the sanitized expression, so we instead
// treat them as barriers directly.
exists(RegexMatch rm | rm instanceof Annotation | this.asExpr() = rm.getString())
}
}
/**
* A method call for encrypting, hashing, or digesting sensitive information. As there are various
* implementations of encryption (reversible and non-reversible) from both JDK and third parties,
* this class simply checks the method name to take a best guess to reduce false positives.
*/
class EncryptedSensitiveMethodCall extends MethodCall {
EncryptedSensitiveMethodCall() {
this.getMethod().getName().toLowerCase().matches(["%encrypt%", "%hash%", "%digest%"])
}
}