Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit f31ed52

Browse files
committed
Clean up InsecureFeatureFlag
Move the flag regexes inline, use `any` instead of a constructor function to select a particular flag kind, and remove explicit limitation on the common superclass FlagKind.
1 parent abfae43 commit f31ed52

File tree

3 files changed

+37
-58
lines changed

3 files changed

+37
-58
lines changed

ql/src/Security/CWE-295/DisabledCertificateCheck.ql

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,22 @@ predicate becomesPartOf(DataFlow::Node part, DataFlow::Node whole) {
3636
exists(Write w | w.writesField(whole.(DataFlow::PostUpdateNode).getPreUpdateNode(), _, part))
3737
}
3838

39+
/**
40+
* Returns flag kinds relevant to this query: a generic security feature flag, or one
41+
* specifically controlling insecure certificate configuration.
42+
*/
43+
FlagKind securityOrTlsVersionFlag() {
44+
result = any(SecurityFeatureFlag f) or
45+
result = any(InsecureCertificateFlag f)
46+
}
47+
3948
/**
4049
* Holds if `name` is (likely to be) a general security flag or one specifically controlling
4150
* an insecure certificate setup.
4251
*/
4352
bindingset[name]
4453
predicate isSecurityOrCertificateConfigFlag(string name) {
45-
isSecurityFlagName(name) or isCertificateFlagName(name)
54+
name = securityOrTlsVersionFlag().getAFlagName()
4655
}
4756

4857
from Write w, DataFlow::Node base, Field f, DataFlow::Node rhs

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,15 @@ predicate isInsecureTlsCipherFlow(DataFlow::PathNode source, DataFlow::PathNode
226226
)
227227
}
228228

229+
/**
230+
* Returns flag kinds relevant to this query: a generic security feature flag, or one
231+
* specifically controlling TLS version selection.
232+
*/
233+
FlagKind securityOrTlsVersionFlag() {
234+
result = any(SecurityFeatureFlag f) or
235+
result = any(LegacyTlsVersionFlag f)
236+
}
237+
229238
from DataFlow::PathNode source, DataFlow::PathNode sink, string message
230239
where
231240
(
@@ -236,11 +245,9 @@ where
236245
not [getASecurityFeatureFlagCheck(), getALegacyTlsVersionCheck()]
237246
.dominatesNode([source, sink].getNode().asInstruction()) and
238247
// Exclude sources or sinks that occur lexically within a block related to a feature or legacy flag
239-
not astNodeIsFlag([source, sink].getNode().asExpr().getParent*(),
240-
[securityFeatureFlag(), legacyTlsVersionFlag()]) and
248+
not astNodeIsFlag([source, sink].getNode().asExpr().getParent*(), securityOrTlsVersionFlag()) and
241249
// Exclude results in functions whose name documents insecurity
242250
not exists(FuncDef fn | fn = sink.getNode().getRoot().getEnclosingFunction*() |
243-
isSecurityFlagName(fn.getName()) or
244-
isLegacyTlsFlagName(fn.getName())
251+
fn.getName() = securityOrTlsVersionFlag().getAFlagName()
245252
)
246253
select sink.getNode(), source, sink, message

ql/src/semmle/go/security/InsecureFeatureFlag.qll

Lines changed: 16 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,12 @@
55
import go
66

77
module InsecureFeatureFlag {
8-
/**
9-
* Holds if `name` may be the name of a feature flag that controls a security feature.
10-
*/
11-
bindingset[name]
12-
predicate isSecurityFlagName(string name) { name.regexpMatch("(?i).*(secure|(en|dis)able).*") }
13-
14-
/**
15-
* Holds if `name` may be the name of a feature flag that controls whether certificate checking is
16-
* enabled.
17-
*/
18-
bindingset[name]
19-
predicate isCertificateFlagName(string name) {
20-
name.regexpMatch("(?i).*(selfCert|selfSign|validat|verif|trust).*")
21-
}
22-
23-
/**
24-
* Holds if `name` suggests an old or legacy version of TLS.
25-
*
26-
* We accept 'intermediate' because it appears to be common for TLS users
27-
* to define three profiles: modern, intermediate, legacy/old, perhaps based
28-
* on https://wiki.mozilla.org/Security/Server_Side_TLS (though note the
29-
* 'intermediate' used there would now pass muster according to this query)
30-
*/
31-
bindingset[name]
32-
predicate isLegacyTlsFlagName(string name) {
33-
name.regexpMatch("(?i).*(old|intermediate|legacy).*")
34-
}
35-
368
/**
379
* A kind of flag that may indicate security expectations regarding the code it guards.
3810
*/
3911
abstract class FlagKind extends string {
40-
FlagKind() {
41-
this = "securityFeature" or this = "legacyTlsVersion" or this = "insecureCertificate"
42-
}
12+
bindingset[this]
13+
FlagKind() { any() }
4314

4415
/**
4516
* Returns a flag name of this type.
@@ -54,44 +25,36 @@ module InsecureFeatureFlag {
5425
SecurityFeatureFlag() { this = "securityFeature" }
5526

5627
bindingset[result]
57-
override string getAFlagName() { isSecurityFlagName(result) }
28+
override string getAFlagName() { result.regexpMatch("(?i).*(secure|(en|dis)able).*") }
5829
}
5930

60-
/**
61-
* Flags suggesting an optional feature, perhaps deliberately insecure.
62-
*/
63-
string securityFeatureFlag() { result = "securityFeature" }
64-
6531
/**
6632
* Flags suggesting support for an old or legacy TLS version.
33+
*
34+
* We accept 'intermediate' because it appears to be common for TLS users
35+
* to define three profiles: modern, intermediate, legacy/old, perhaps based
36+
* on https://wiki.mozilla.org/Security/Server_Side_TLS (though note the
37+
* 'intermediate' used there would now pass muster according to this query)
6738
*/
6839
class LegacyTlsVersionFlag extends FlagKind {
6940
LegacyTlsVersionFlag() { this = "legacyTlsVersion" }
7041

7142
bindingset[result]
72-
override string getAFlagName() { isLegacyTlsFlagName(result) }
43+
override string getAFlagName() { result.regexpMatch("(?i).*(old|intermediate|legacy).*") }
7344
}
7445

75-
/**
76-
* Flags suggesting support for an old or legacy TLS version.
77-
*/
78-
string legacyTlsVersionFlag() { result = "legacyTlsVersion" }
79-
8046
/**
8147
* Flags suggesting a deliberately insecure certificate setup.
8248
*/
8349
class InsecureCertificateFlag extends FlagKind {
8450
InsecureCertificateFlag() { this = "insecureCertificate" }
8551

8652
bindingset[result]
87-
override string getAFlagName() { isCertificateFlagName(result) }
53+
override string getAFlagName() {
54+
result.regexpMatch("(?i).*(selfCert|selfSign|validat|verif|trust).*")
55+
}
8856
}
8957

90-
/**
91-
* Flags suggesting support for an old or legacy feature.
92-
*/
93-
string insecureCertificateFlag() { result = "insecureCertificate" }
94-
9558
/** Gets a global value number representing a (likely) security flag. */
9659
GVN getAFlag(FlagKind flagKind) {
9760
// a call like `cfg.disableVerification()`
@@ -151,7 +114,7 @@ module InsecureFeatureFlag {
151114
}
152115

153116
/**
154-
* Holds if `node` suggests an old TLS version according to `flagKind`.
117+
* Holds if `node` involves a string of kind `flagKind`.
155118
*/
156119
predicate astNodeIsFlag(AstNode node, FlagKind flagKind) {
157120
// Map literal flag: value or "flag": value
@@ -177,20 +140,20 @@ module InsecureFeatureFlag {
177140
* Gets a control-flow node that represents a (likely) security feature-flag check
178141
*/
179142
ControlFlow::ConditionGuardNode getASecurityFeatureFlagCheck() {
180-
result.ensures(getAFlag(securityFeatureFlag()).getANode(), _)
143+
result.ensures(getAFlag(any(SecurityFeatureFlag f)).getANode(), _)
181144
}
182145

183146
/**
184147
* Gets a control-flow node that represents a (likely) flag controlling TLS version selection.
185148
*/
186149
ControlFlow::ConditionGuardNode getALegacyTlsVersionCheck() {
187-
result.ensures(getAFlag(legacyTlsVersionFlag()).getANode(), _)
150+
result.ensures(getAFlag(any(LegacyTlsVersionFlag f)).getANode(), _)
188151
}
189152

190153
/**
191154
* Gets a control-flow node that represents a (likely) flag controlling an insecure certificate setup.
192155
*/
193156
ControlFlow::ConditionGuardNode getAnInsecureCertificateCheck() {
194-
result.ensures(getAFlag(insecureCertificateFlag()).getANode(), _)
157+
result.ensures(getAFlag(any(InsecureCertificateFlag f)).getANode(), _)
195158
}
196159
}

0 commit comments

Comments
 (0)