@@ -34,6 +34,9 @@ predicate isTestFile(DataFlow::Node node) {
34
34
)
35
35
}
36
36
37
+ /**
38
+ * Holds if it is insecure to assign TLS version `val` named `named` to `tls.Config` field `fieldName`
39
+ */
37
40
predicate isInsecureTlsVersion ( int val , string name , string fieldName ) {
38
41
( fieldName = "MinVersion" or fieldName = "MaxVersion" ) and
39
42
// tls.VersionSSL30
@@ -103,11 +106,17 @@ predicate isReturnedWithError(DataFlow::Node node) {
103
106
class TlsVersionFlowConfig extends TaintTracking:: Configuration {
104
107
TlsVersionFlowConfig ( ) { this = "TlsVersionFlowConfig" }
105
108
109
+ /**
110
+ * Holds if `source` is a TLS version source yielding value `val`.
111
+ */
106
112
predicate isSource ( DataFlow:: Node source , int val ) {
107
113
val = source .getIntValue ( ) and
108
114
not isReturnedWithError ( source )
109
115
}
110
116
117
+ /**
118
+ * Holds if `fieldWrite` writes `sink` to `base`.`fld`, where `fld` is a TLS version field.
119
+ */
111
120
predicate isSink ( DataFlow:: Node sink , Field fld , DataFlow:: Node base , Write fieldWrite ) {
112
121
fld .hasQualifiedName ( "crypto/tls" , "Config" , [ "MinVersion" , "MaxVersion" ] ) and
113
122
fieldWrite = fld .getAWrite ( ) and
@@ -162,9 +171,13 @@ DataFlow::Node nodeOrDeref(DataFlow::Node node) {
162
171
}
163
172
164
173
/**
165
- * Find insecure TLS versions.
174
+ * Holds if an insecure TLS version flows from `source` to `sink`, which is in turn written
175
+ * to a field of `base`. `message` describes the specific problem found.
176
+ *
177
+ * Contexts suggesting an intentionally insecure or legacy configuration are excluded (see
178
+ * `nodeSuggestsOldVersion`), as are fields that may conditionally receive a modern TLS version.
166
179
*/
167
- query predicate checkTlsVersions (
180
+ predicate isInsecureTlsVersionFlow (
168
181
DataFlow:: PathNode source , DataFlow:: PathNode sink , string message , DataFlow:: Node base
169
182
) {
170
183
exists ( TlsVersionFlowConfig cfg , int version , Field fld |
@@ -201,6 +214,9 @@ query predicate checkTlsVersions(
201
214
class TlsInsecureCipherSuitesFlowConfig extends TaintTracking:: Configuration {
202
215
TlsInsecureCipherSuitesFlowConfig ( ) { this = "TlsInsecureCipherSuitesFlowConfig" }
203
216
217
+ /**
218
+ * Holds if `source` reads an insecure TLS cipher suite named `suiteName`.
219
+ */
204
220
predicate isSourceValueEntity ( DataFlow:: Node source , string suiteName ) {
205
221
exists ( DataFlow:: ValueEntity val |
206
222
val .hasQualifiedName ( "crypto/tls" , suiteName ) and
@@ -214,6 +230,9 @@ class TlsInsecureCipherSuitesFlowConfig extends TaintTracking::Configuration {
214
230
)
215
231
}
216
232
233
+ /**
234
+ * Holds if `source` represents the result of `tls.InsecureCipherSuites()`.
235
+ */
217
236
predicate isSourceInsecureCipherSuites ( DataFlow:: Node source ) {
218
237
exists ( Function insecureCipherSuites |
219
238
insecureCipherSuites .hasQualifiedName ( "crypto/tls" , "InsecureCipherSuites" )
@@ -229,6 +248,10 @@ class TlsInsecureCipherSuitesFlowConfig extends TaintTracking::Configuration {
229
248
isSourceValueEntity ( source , _)
230
249
}
231
250
251
+ /**
252
+ * Holds if `fieldWrite` writes `sink` to `base`.`fld`, and `fld` is `tls.Config.CipherSuites`,
253
+ * and no parent of `base` is named suggesting an intentionally insecure configuration.
254
+ */
232
255
predicate isSink ( DataFlow:: Node sink , Field fld , DataFlow:: Node base , Write fieldWrite ) {
233
256
fld .hasQualifiedName ( "crypto/tls" , "Config" , "CipherSuites" ) and
234
257
fieldWrite = fld .getAWrite ( ) and
@@ -249,11 +272,11 @@ class TlsInsecureCipherSuitesFlowConfig extends TaintTracking::Configuration {
249
272
}
250
273
251
274
/**
252
- * Find insecure TLS cipher suites.
275
+ * Holds if an insecure TLS cipher suite flows from `source` to `sink`, where `sink`
276
+ * is written to the CipherSuites list of a `tls.Config` instance. `message` describes
277
+ * the exact problem found.
253
278
*/
254
- predicate checkTlsInsecureCipherSuites (
255
- DataFlow:: PathNode source , DataFlow:: PathNode sink , string message
256
- ) {
279
+ predicate isInsecureTlsCipherFlow ( DataFlow:: PathNode source , DataFlow:: PathNode sink , string message ) {
257
280
exists ( TlsInsecureCipherSuitesFlowConfig cfg | cfg .hasFlowPath ( source , sink ) |
258
281
exists ( string name | cfg .isSourceValueEntity ( source .getNode ( ) , name ) |
259
282
message = "Use of an insecure cipher suite: " + name + "."
@@ -267,12 +290,12 @@ predicate checkTlsInsecureCipherSuites(
267
290
from DataFlow:: PathNode source , DataFlow:: PathNode sink , string message
268
291
where
269
292
(
270
- checkTlsVersions ( source , sink , message , _) or
271
- checkTlsInsecureCipherSuites ( source , sink , message )
293
+ isInsecureTlsVersionFlow ( source , sink , message , _) or
294
+ isInsecureTlsCipherFlow ( source , sink , message )
272
295
) and
273
296
// Exclude sinks guarded by a feature flag
274
297
not getAFeatureFlagCheck ( ) .dominatesNode ( sink .getNode ( ) .asInstruction ( ) ) and
275
- // Exclude results in functions whose name documents the insecurity
298
+ // Exclude results in functions whose name documents insecurity
276
299
not exists ( FuncDef fn | fn = sink .getNode ( ) .asInstruction ( ) .getRoot ( ) |
277
300
isFeatureFlagName ( fn .getEnclosingFunction * ( ) .getName ( ) ) or
278
301
isOldVersionName ( fn .getEnclosingFunction * ( ) .getName ( ) )
0 commit comments