forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInsecureRandomness.ql
More file actions
113 lines (99 loc) · 3.77 KB
/
InsecureRandomness.ql
File metadata and controls
113 lines (99 loc) · 3.77 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* @name Insecure randomness
* @description Using a cryptographically weak pseudo-random number generator to generate a
* security sensitive value may allow an attacker to predict what sensitive value will
* be generated.
* @kind path-problem
* @problem.severity warning
* @precision high
* @id cs/insecure-randomness
* @tags security
* external/cwe/cwe-338
*/
import csharp
import semmle.code.csharp.frameworks.Test
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
module Random {
import semmle.code.csharp.security.dataflow.flowsources.Remote
import semmle.code.csharp.security.SensitiveActions
/**
* A data flow sink for insecure randomness in security sensitive context.
*/
abstract class Sink extends DataFlow::ExprNode { }
/**
* A data flow source for insecure randomness in security sensitive context.
*/
abstract class Source extends DataFlow::ExprNode { }
/**
* A sanitizer for insecure randomness in security sensitive context.
*/
abstract class Sanitizer extends DataFlow::ExprNode { }
/**
* A taint-tracking configuration for insecure randomness in security sensitive context.
*/
class TaintTrackingConfiguration extends TaintTracking::Configuration {
TaintTrackingConfiguration() { this = "RandomDataFlowConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
// succ = array_or_indexer[pred] - use of random numbers in an index
succ.asExpr().(ElementAccess).getAnIndex() = pred.asExpr()
}
}
/** A source of cryptographically insecure random numbers. */
class RandomSource extends Source {
RandomSource() {
this.getExpr() =
any(MethodCall mc |
mc.getQualifier().getType().(RefType).hasQualifiedName("System", "Random")
)
}
}
/** A value assigned to a property, variable or parameter which holds security sensitive data. */
class SensitiveSink extends Sink {
SensitiveSink() {
exists(Expr e |
// Simple assignment
e = this.getExpr()
|
e = any(SensitiveVariable v).getAnAssignedValue()
or
e = any(SensitiveProperty v).getAnAssignedValue()
or
e = any(SensitiveLibraryParameter v).getAnAssignedArgument()
or
// Assignment operation, e.g. += or similar
exists(AssignOperation ao |
ao.getRValue() = e and
// "expanded" assignments will be covered by simple assignment
not ao.hasExpandedAssignment()
|
ao.getLValue() = any(SensitiveVariable v).getAnAccess() or
ao.getLValue() = any(SensitiveProperty v).getAnAccess() or
ao.getLValue() = any(SensitiveLibraryParameter v).getAnAccess()
)
)
}
}
/**
* Stop tracking beyond first assignment to sensitive element, so as to remove duplication in the
* reported results.
*/
class AlreadyTrackedSanitizer extends Sanitizer {
AlreadyTrackedSanitizer() {
exists(Expr e | e = this.getExpr() |
e = any(SensitiveVariable v).getAnAccess() or
e = any(SensitiveProperty v).getAnAccess() or
e = any(SensitiveLibraryParameter v).getAnAccess()
)
}
}
}
from
Random::TaintTrackingConfiguration randomTracking, DataFlow::PathNode source,
DataFlow::PathNode sink
where randomTracking.hasFlowPath(source, sink)
select sink.getNode(), source, sink,
"Cryptographically insecure random number is generated at $@ and used here in a security context.",
source.getNode(), source.getNode().toString()