-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathLanguage.qll
More file actions
112 lines (87 loc) · 3.58 KB
/
Language.qll
File metadata and controls
112 lines (87 loc) · 3.58 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
private import cpp as Language
import semmle.code.cpp.dataflow.new.TaintTracking
import codeql.quantum.experimental.Model
private import OpenSSL.GenericSourceCandidateLiteral
module CryptoInput implements InputSig<Language::Location> {
class DataFlowNode = DataFlow::Node;
class LocatableElement = Language::Locatable;
class UnknownLocation = Language::UnknownLocation;
LocatableElement dfn_to_element(DataFlow::Node node) {
result = node.asExpr() or
result = node.asParameter() or
result = node.asVariable() or
result = node.asDefiningArgument() or
result = node.asIndirectExpr()
}
string locationToFileBaseNameAndLineNumberString(Location location) {
result = location.getFile().getBaseName() + ":" + location.getStartLine()
}
predicate artifactOutputFlowsToGenericInput(
DataFlow::Node artifactOutput, DataFlow::Node otherInput
) {
ArtifactFlow::flow(artifactOutput, otherInput)
}
}
module Crypto = CryptographyBase<Language::Location, CryptoInput>;
module ArtifactFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source = any(Crypto::ArtifactInstance artifact).getOutputNode()
}
predicate isSink(DataFlow::Node sink) {
sink = any(Crypto::FlowAwareElement other).getInputNode()
}
predicate isBarrierOut(DataFlow::Node node) {
node = any(Crypto::FlowAwareElement element).getInputNode()
}
predicate isBarrierIn(DataFlow::Node node) {
node = any(Crypto::FlowAwareElement element).getOutputNode()
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
node1.(AdditionalFlowInputStep).getOutput() = node2
}
}
module ArtifactFlow = TaintTracking::Global<ArtifactFlowConfig>;
/**
* An artifact output to node input configuration
*/
abstract class AdditionalFlowInputStep extends DataFlow::Node {
abstract DataFlow::Node getOutput();
final DataFlow::Node getInput() { result = this }
}
/**
* Generic data source to node input configuration
*/
module GenericDataSourceFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source = any(Crypto::GenericSourceInstance i).getOutputNode()
}
predicate isSink(DataFlow::Node sink) {
sink = any(Crypto::FlowAwareElement other).getInputNode()
}
predicate isBarrierOut(DataFlow::Node node) {
node = any(Crypto::FlowAwareElement element).getInputNode()
}
predicate isBarrierIn(DataFlow::Node node) {
node = any(Crypto::FlowAwareElement element).getOutputNode()
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
node1.(AdditionalFlowInputStep).getOutput() = node2
}
}
module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig>;
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof OpenSslGenericSourceCandidateLiteral
{
override DataFlow::Node getOutputNode() {
// OpenSSL algorithms may be referenced either by string name or by numeric ID:
// String names (e.g. "AES-256-CBC") appear in the AST as character pointer
// literals. For these we must use `asIndirectExpr`. Numeric IDs (e.g. NID_aes_256_cbc)
// appear as integer literals. For these, we must use `asExpr` to get the "value" node.
[result.asIndirectExpr(), result.asExpr()] = this
}
override predicate flowsTo(Crypto::FlowAwareElement other) {
// TODO: separate config to avoid blowing up data-flow analysis
GenericDataSourceFlow::flow(this.getOutputNode(), other.getInputNode())
}
override string getAdditionalDescription() { result = this.toString() }
}
import OpenSSL.OpenSSL