Skip to content

Commit 9bcf7c5

Browse files
committed
Go: HardcodedCredentials
1 parent 0e9f816 commit 9bcf7c5

File tree

2 files changed

+57
-37
lines changed

2 files changed

+57
-37
lines changed

go/ql/lib/semmle/go/security/HardcodedCredentials.qll

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,23 @@ module HardcodedCredentials {
3636
}
3737

3838
Location getASelectedSourceLocation(DataFlow::Node source) {
39-
none() // TODO: Make sure that this source location matches the query's select clause: Column 1 does not select a source or sink originating from the flow call on line 62 (/Users/d10c/src/semmle-code/ql/go/ql/src/Security/CWE-798/HardcodedCredentials.ql@65:8:65:11), Column 3 does not select a source or sink originating from the flow call on line 62 (/Users/d10c/src/semmle-code/ql/go/ql/src/Security/CWE-798/HardcodedCredentials.ql@65:23:65:28)
39+
result = source.getLocation()
40+
or
41+
exists(DataFlow::Node node | result = node.getLocation() |
42+
sensitiveAssignment(node, _, _)
43+
or
44+
hardcodedPrivateKey(node, _)
45+
)
4046
}
4147

4248
Location getASelectedSinkLocation(DataFlow::Node sink) {
43-
none() // TODO: Make sure that this sink location matches the query's select clause: Column 1 does not select a source or sink originating from the flow call on line 62 (/Users/d10c/src/semmle-code/ql/go/ql/src/Security/CWE-798/HardcodedCredentials.ql@65:8:65:11), Column 3 does not select a source or sink originating from the flow call on line 62 (/Users/d10c/src/semmle-code/ql/go/ql/src/Security/CWE-798/HardcodedCredentials.ql@65:23:65:28)
49+
result = sink.getLocation()
50+
or
51+
exists(DataFlow::Node node | result = node.getLocation() |
52+
sensitiveAssignment(_, node, _)
53+
or
54+
hardcodedPrivateKey(node, _)
55+
)
4456
}
4557
}
4658

@@ -142,4 +154,45 @@ module HardcodedCredentials {
142154
)
143155
}
144156
}
157+
158+
/**
159+
* Holds if `sink` is used in a context that suggests it may hold sensitive data of
160+
* the given `type`.
161+
*/
162+
private predicate isSensitive(DataFlow::Node sink, SensitiveExpr::Classification type) {
163+
exists(Write write, string name |
164+
pragma[only_bind_out](write).getRhs() = sink and
165+
name = pragma[only_bind_out](write).getLhs().getName() and
166+
// allow obvious test password variables
167+
not name.regexpMatch(HeuristicNames::notSensitive())
168+
|
169+
name.regexpMatch(HeuristicNames::maybeSensitive(type))
170+
)
171+
}
172+
173+
/**
174+
* Holds if `source` locally flows to a `sink` that is used in a context that suggests
175+
* it may hold sensitive data of the given `type`.
176+
*/
177+
predicate sensitiveAssignment(
178+
DataFlow::Node source, DataFlow::Node sink, SensitiveExpr::Classification type
179+
) {
180+
exists(string val | val = source.getStringValue() and val != "" |
181+
DataFlow::localFlow(source, sink) and
182+
isSensitive(sink, type) and
183+
// allow obvious dummy/test values
184+
not PasswordHeuristics::isDummyPassword(val) and
185+
not sink.asExpr().(Ident).getName().regexpMatch(HeuristicNames::notSensitive())
186+
)
187+
}
188+
189+
/**
190+
* Holds if `node` is a hardcoded private key.
191+
* The type is set to `SensitiveExpr::certificate()`.
192+
*/
193+
predicate hardcodedPrivateKey(DataFlow::Node node, SensitiveExpr::Classification type) {
194+
node.getStringValue()
195+
.regexpMatch("(?s)-+BEGIN\\b.*\\bPRIVATE KEY-+.+-+END\\b.*\\bPRIVATE KEY-+\n?") and
196+
type = SensitiveExpr::certificate()
197+
}
145198
}

go/ql/src/Security/CWE-798/HardcodedCredentials.ql

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,12 @@ import go
1717
import semmle.go.security.HardcodedCredentials
1818
import semmle.go.security.SensitiveActions
1919

20-
/**
21-
* Holds if `sink` is used in a context that suggests it may hold sensitive data of
22-
* the given `type`.
23-
*/
24-
predicate isSensitive(DataFlow::Node sink, SensitiveExpr::Classification type) {
25-
exists(Write write, string name |
26-
pragma[only_bind_out](write).getRhs() = sink and
27-
name = pragma[only_bind_out](write).getLhs().getName() and
28-
// allow obvious test password variables
29-
not name.regexpMatch(HeuristicNames::notSensitive())
30-
|
31-
name.regexpMatch(HeuristicNames::maybeSensitive(type))
32-
)
33-
}
34-
35-
predicate sensitiveAssignment(
36-
DataFlow::Node source, DataFlow::Node sink, SensitiveExpr::Classification type
37-
) {
38-
exists(string val | val = source.getStringValue() and val != "" |
39-
DataFlow::localFlow(source, sink) and
40-
isSensitive(sink, type) and
41-
// allow obvious dummy/test values
42-
not PasswordHeuristics::isDummyPassword(val) and
43-
not sink.asExpr().(Ident).getName().regexpMatch(HeuristicNames::notSensitive())
44-
)
45-
}
46-
47-
predicate hardcodedPrivateKey(DataFlow::Node node, SensitiveExpr::Classification type) {
48-
node.getStringValue()
49-
.regexpMatch("(?s)-+BEGIN\\b.*\\bPRIVATE KEY-+.+-+END\\b.*\\bPRIVATE KEY-+\n?") and
50-
type = SensitiveExpr::certificate()
51-
}
52-
5320
from DataFlow::Node source, string message, DataFlow::Node sink, SensitiveExpr::Classification type
5421
where
55-
sensitiveAssignment(source, sink, type) and
22+
HardcodedCredentials::sensitiveAssignment(source, sink, type) and
5623
message = "Hard-coded $@."
5724
or
58-
hardcodedPrivateKey(source, type) and
25+
HardcodedCredentials::hardcodedPrivateKey(source, type) and
5926
source = sink and
6027
message = "Hard-coded private key."
6128
or

0 commit comments

Comments
 (0)