Skip to content

Commit 442dfc1

Browse files
committed
Make InsecureTLS use new API
1 parent b00e447 commit 442dfc1

1 file changed

Lines changed: 52 additions & 44 deletions

File tree

go/ql/src/Security/CWE-327/InsecureTLS.ql

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
*/
1313

1414
import go
15-
import DataFlow::PathGraph
1615
import semmle.go.security.InsecureFeatureFlag::InsecureFeatureFlag
1716

1817
/**
@@ -55,13 +54,11 @@ int getATlsVersion() { result = getASecureTlsVersion() or isInsecureTlsVersion(r
5554
* A taint-tracking configuration for tracking flow from TLS versions to the
5655
* `tls.Config.MinVersion` and `tls.Config.MaxVersion` fields.
5756
*/
58-
class TlsVersionFlowConfig extends TaintTracking::Configuration {
59-
TlsVersionFlowConfig() { this = "TlsVersionFlowConfig" }
60-
57+
module TlsVersionFlowConfig implements DataFlow::ConfigSig {
6158
/**
6259
* Holds if `source` is a TLS version source yielding value `val`.
6360
*/
64-
predicate intIsSource(DataFlow::Node source, int val) {
61+
additional predicate intIsSource(DataFlow::Node source, int val) {
6562
val = source.getIntValue() and
6663
val = getATlsVersion() and
6764
not DataFlow::isReturnedWithError(source)
@@ -70,43 +67,43 @@ class TlsVersionFlowConfig extends TaintTracking::Configuration {
7067
/**
7168
* Holds if `fieldWrite` writes `sink` to `base`.`fld`, where `fld` is a TLS version field.
7269
*/
73-
predicate isSink(DataFlow::Node sink, Field fld, DataFlow::Node base, Write fieldWrite) {
70+
additional predicate isSink(DataFlow::Node sink, Field fld, DataFlow::Node base, Write fieldWrite) {
7471
fld.hasQualifiedName("crypto/tls", "Config", ["MinVersion", "MaxVersion"]) and
7572
fieldWrite.writesField(base, fld, sink)
7673
}
7774

78-
override predicate isSource(DataFlow::Node source) { this.intIsSource(source, _) }
75+
predicate isSource(DataFlow::Node source) { intIsSource(source, _) }
7976

80-
override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _, _, _) }
77+
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _, _) }
8178
}
8279

80+
module TlsVersionFlow = TaintTracking::Global<TlsVersionFlowConfig>;
81+
8382
/**
8483
* Holds if `config` exhibits a secure TLS version flowing from `source` to `sink`, which flows into `fld`.
8584
*/
86-
predicate secureTlsVersionFlow(
87-
TlsVersionFlowConfig config, DataFlow::PathNode source, DataFlow::PathNode sink, Field fld
88-
) {
85+
predicate secureTlsVersionFlow(DataFlow::Node source, DataFlow::Node sink, Field fld) {
8986
exists(int version |
90-
config.hasFlowPath(source, sink) and
91-
config.intIsSource(source.getNode(), version) and
87+
TlsVersionFlow::flow(source, sink) and
88+
TlsVersionFlowConfig::intIsSource(source, version) and
9289
not isInsecureTlsVersion(version, _, fld.getName())
9390
)
9491
}
9592

9693
/**
9794
* Holds if a secure TLS version reaches `sink`, which flows into `fld`.
9895
*/
99-
predicate secureTlsVersionFlowsToSink(DataFlow::PathNode sink, Field fld) {
100-
secureTlsVersionFlow(_, _, sink, fld)
96+
predicate secureTlsVersionFlowsToSink(DataFlow::Node sink, Field fld) {
97+
secureTlsVersionFlow(_, sink, fld)
10198
}
10299

103100
/**
104101
* Holds if a secure TLS version may reach `accessPath`.`fld`
105102
*/
106103
predicate secureTlsVersionFlowsToField(SsaWithFields accessPath, Field fld) {
107-
exists(TlsVersionFlowConfig config, DataFlow::PathNode sink, DataFlow::Node base |
108-
secureTlsVersionFlow(config, _, sink, fld) and
109-
config.isSink(sink.getNode(), fld, base, _) and
104+
exists(DataFlow::Node sink, DataFlow::Node base |
105+
secureTlsVersionFlow(_, sink, fld) and
106+
TlsVersionFlowConfig::isSink(sink, fld, base, _) and
110107
accessPath.getAUse() = base
111108
)
112109
}
@@ -124,17 +121,18 @@ DataFlow::Node nodeOrDeref(DataFlow::Node node) {
124121
* to a field of `base`. `message` describes the specific problem found.
125122
*/
126123
predicate isInsecureTlsVersionFlow(
127-
DataFlow::PathNode source, DataFlow::PathNode sink, string message, DataFlow::Node base
124+
TlsVersionFlow::PathNode source, TlsVersionFlow::PathNode sink, string message,
125+
DataFlow::Node base
128126
) {
129-
exists(TlsVersionFlowConfig cfg, int version, Field fld |
130-
cfg.hasFlowPath(source, sink) and
131-
cfg.intIsSource(source.getNode(), version) and
132-
cfg.isSink(sink.getNode(), fld, base, _) and
127+
exists(int version, Field fld |
128+
TlsVersionFlow::flowPath(source, sink) and
129+
TlsVersionFlowConfig::intIsSource(source.getNode(), version) and
130+
TlsVersionFlowConfig::isSink(sink.getNode(), fld, base, _) and
133131
isInsecureTlsVersion(version, _, fld.getName()) and
134132
// Exclude cases where a secure TLS version can also flow to the same
135133
// sink, or to different sinks that refer to the same base and field,
136134
// which suggests a configurable security mode.
137-
not secureTlsVersionFlowsToSink(sink, fld) and
135+
not secureTlsVersionFlowsToSink(sink.getNode(), fld) and
138136
not exists(SsaWithFields insecureAccessPath, SsaWithFields secureAccessPath |
139137
nodeOrDeref(insecureAccessPath.getAUse()) = base and
140138
secureAccessPath = insecureAccessPath.similar()
@@ -156,13 +154,11 @@ predicate isInsecureTlsVersionFlow(
156154
* A taint-tracking configuration for tracking flow from insecure TLS cipher
157155
* suites into a `tls.Config` struct, to the `CipherSuites` field.
158156
*/
159-
class TlsInsecureCipherSuitesFlowConfig extends TaintTracking::Configuration {
160-
TlsInsecureCipherSuitesFlowConfig() { this = "TlsInsecureCipherSuitesFlowConfig" }
161-
157+
module TlsInsecureCipherSuitesFlowConfig implements DataFlow::ConfigSig {
162158
/**
163159
* Holds if `source` reads an insecure TLS cipher suite named `suiteName`.
164160
*/
165-
predicate isSourceValueEntity(DataFlow::Node source, string suiteName) {
161+
additional predicate isSourceValueEntity(DataFlow::Node source, string suiteName) {
166162
exists(DataFlow::ValueEntity val |
167163
val.hasQualifiedName("crypto/tls", suiteName) and
168164
suiteName =
@@ -179,52 +175,58 @@ class TlsInsecureCipherSuitesFlowConfig extends TaintTracking::Configuration {
179175
/**
180176
* Holds if `source` represents the result of `tls.InsecureCipherSuites()`.
181177
*/
182-
predicate isSourceInsecureCipherSuites(DataFlow::Node source) {
178+
additional predicate isSourceInsecureCipherSuites(DataFlow::Node source) {
183179
exists(Function insecureCipherSuites |
184180
insecureCipherSuites.hasQualifiedName("crypto/tls", "InsecureCipherSuites")
185181
|
186182
source = insecureCipherSuites.getACall().getResult()
187183
)
188184
}
189185

190-
override predicate isSource(DataFlow::Node source) {
191-
this.isSourceInsecureCipherSuites(source)
186+
predicate isSource(DataFlow::Node source) {
187+
isSourceInsecureCipherSuites(source)
192188
or
193-
this.isSourceValueEntity(source, _)
189+
isSourceValueEntity(source, _)
194190
}
195191

196192
/**
197193
* Holds if `fieldWrite` writes `sink` to `base`.`fld`, and `fld` is `tls.Config.CipherSuites`.
198194
*/
199-
predicate isSink(DataFlow::Node sink, Field fld, DataFlow::Node base, Write fieldWrite) {
195+
additional predicate isSink(DataFlow::Node sink, Field fld, DataFlow::Node base, Write fieldWrite) {
200196
fld.hasQualifiedName("crypto/tls", "Config", "CipherSuites") and
201197
fieldWrite.writesField(base, fld, sink)
202198
}
203199

204-
override predicate isSink(DataFlow::Node sink) { this.isSink(sink, _, _, _) }
200+
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _, _) }
205201

206202
/**
207203
* Declare sinks as out-sanitizers in order to avoid producing superfluous paths where a cipher
208204
* is written to CipherSuites, then the list is further extended with either safe or tainted
209205
* suites.
210206
*/
211-
override predicate isSanitizerOut(DataFlow::Node node) {
212-
super.isSanitizerOut(node) or this.isSink(node)
213-
}
207+
predicate isBarrierOut(DataFlow::Node node) { isSink(node) }
214208
}
215209

210+
module TlsInsecureCipherSuitesFlow = TaintTracking::Global<TlsInsecureCipherSuitesFlowConfig>;
211+
216212
/**
217213
* Holds if an insecure TLS cipher suite flows from `source` to `sink`, where `sink`
218214
* is written to the CipherSuites list of a `tls.Config` instance. `message` describes
219215
* the exact problem found.
220216
*/
221-
predicate isInsecureTlsCipherFlow(DataFlow::PathNode source, DataFlow::PathNode sink, string message) {
222-
exists(TlsInsecureCipherSuitesFlowConfig cfg | cfg.hasFlowPath(source, sink) |
223-
exists(string name | cfg.isSourceValueEntity(source.getNode(), name) |
217+
predicate isInsecureTlsCipherFlow(
218+
TlsInsecureCipherSuitesFlow::PathNode source, TlsInsecureCipherSuitesFlow::PathNode sink,
219+
string message
220+
) {
221+
TlsInsecureCipherSuitesFlow::flowPath(source, sink) and
222+
(
223+
exists(string name |
224+
TlsInsecureCipherSuitesFlowConfig::isSourceValueEntity(source.getNode(), name)
225+
|
224226
message = "Use of an insecure cipher suite: " + name + "."
225227
)
226228
or
227-
cfg.isSourceInsecureCipherSuites(source.getNode()) and
229+
TlsInsecureCipherSuitesFlowConfig::isSourceInsecureCipherSuites(source.getNode()) and
228230
message = "Use of an insecure cipher suite."
229231
)
230232
}
@@ -260,11 +262,17 @@ FlagKind securityOrTlsVersionFlag() {
260262
result = any(LegacyTlsVersionFlag f)
261263
}
262264

263-
from DataFlow::PathNode source, DataFlow::PathNode sink, string message
265+
module Flow =
266+
DataFlow::MergePathGraph<TlsVersionFlow::PathNode, TlsInsecureCipherSuitesFlow::PathNode,
267+
TlsVersionFlow::PathGraph, TlsInsecureCipherSuitesFlow::PathGraph>;
268+
269+
import Flow::PathGraph
270+
271+
from Flow::PathNode source, Flow::PathNode sink, string message
264272
where
265273
(
266-
isInsecureTlsVersionFlow(source, sink, message, _) or
267-
isInsecureTlsCipherFlow(source, sink, message)
274+
isInsecureTlsVersionFlow(source.asPathNode1(), sink.asPathNode1(), message, _) or
275+
isInsecureTlsCipherFlow(source.asPathNode2(), sink.asPathNode2(), message)
268276
) and
269277
// Exclude sources or sinks guarded by a feature or legacy flag
270278
not [getASecurityFeatureFlagCheck(), getALegacyTlsVersionCheck()]

0 commit comments

Comments
 (0)