Skip to content

Commit 2698b61

Browse files
committed
Refactor HardcodedCredentialsApiCall.qll
1 parent e8f7e3f commit 2698b61

File tree

3 files changed

+57
-8
lines changed

3 files changed

+57
-8
lines changed

java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ import semmle.code.java.dataflow.DataFlow
77
import HardcodedCredentials
88

99
/**
10+
* DEPRECATED: Use `HardcodedCredentialApiCallFlow` instead.
11+
*
1012
* A data-flow configuration that tracks flow from a hard-coded credential in a call to a sensitive Java API which may compromise security.
1113
*/
12-
class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration {
14+
deprecated class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration {
1315
HardcodedCredentialApiCallConfiguration() { this = "HardcodedCredentialApiCallConfiguration" }
1416

1517
override predicate isSource(DataFlow::Node n) {
@@ -52,3 +54,53 @@ class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration {
5254
n.asExpr().(MethodAccess).getMethod() instanceof MethodSystemGetenv
5355
}
5456
}
57+
58+
/**
59+
* A data-flow configuration that tracks flow from a hard-coded credential in a call to a sensitive Java API which may compromise security.
60+
*/
61+
private module HardcodedCredentialApiCallConfig implements DataFlow::ConfigSig {
62+
predicate isSource(DataFlow::Node n) {
63+
n.asExpr() instanceof HardcodedExpr and
64+
not n.asExpr().getEnclosingCallable() instanceof ToStringMethod
65+
}
66+
67+
predicate isSink(DataFlow::Node n) { n.asExpr() instanceof CredentialsApiSink }
68+
69+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
70+
node1.asExpr().getType() instanceof TypeString and
71+
(
72+
exists(MethodAccess ma | ma.getMethod().hasName(["getBytes", "toCharArray"]) |
73+
node2.asExpr() = ma and
74+
ma.getQualifier() = node1.asExpr()
75+
)
76+
or
77+
// These base64 routines are usually taint propagators, and this is not a general
78+
// TaintTracking::Configuration, so we must specifically include them here
79+
// as a common transform applied to a constant before passing to a remote API.
80+
exists(MethodAccess ma |
81+
ma.getMethod()
82+
.hasQualifiedName([
83+
"java.util", "cn.hutool.core.codec", "org.apache.shiro.codec",
84+
"apache.commons.codec.binary", "org.springframework.util"
85+
], ["Base64$Encoder", "Base64$Decoder", "Base64", "Base64Utils"],
86+
[
87+
"encode", "encodeToString", "decode", "decodeBase64", "encodeBase64",
88+
"encodeBase64Chunked", "encodeBase64String", "encodeBase64URLSafe",
89+
"encodeBase64URLSafeString"
90+
])
91+
|
92+
node1.asExpr() = ma.getArgument(0) and
93+
node2.asExpr() = ma
94+
)
95+
)
96+
}
97+
98+
predicate isBarrier(DataFlow::Node n) {
99+
n.asExpr().(MethodAccess).getMethod() instanceof MethodSystemGetenv
100+
}
101+
}
102+
103+
/**
104+
* Tracks flow from a hard-coded credential in a call to a sensitive Java API which may compromise security.
105+
*/
106+
module HardcodedCredentialApiCallFlow = DataFlow::Global<HardcodedCredentialApiCallConfig>;

java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@
1111
*/
1212

1313
import semmle.code.java.security.HardcodedCredentialsApiCallQuery
14-
import DataFlow::PathGraph
14+
import HardcodedCredentialApiCallFlow::PathGraph
1515

16-
from
17-
DataFlow::PathNode source, DataFlow::PathNode sink, HardcodedCredentialApiCallConfiguration conf
18-
where conf.hasFlowPath(source, sink)
16+
from HardcodedCredentialApiCallFlow::PathNode source, HardcodedCredentialApiCallFlow::PathNode sink
17+
where HardcodedCredentialApiCallFlow::flowPath(source, sink)
1918
select source.getNode(), source, sink, "Hard-coded value flows to $@.", sink.getNode(),
2019
"sensitive API call"

java/ql/test/query-tests/security/CWE-798/semmle/tests/HardcodedCredentialsApiCall.ql

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ class HardcodedCredentialsApiCallTest extends InlineExpectationsTest {
99

1010
override predicate hasActualResult(Location location, string element, string tag, string value) {
1111
tag = "HardcodedCredentialsApiCall" and
12-
exists(DataFlow::Node sink, HardcodedCredentialApiCallConfiguration conf |
13-
conf.hasFlow(_, sink)
14-
|
12+
exists(DataFlow::Node sink | HardcodedCredentialApiCallFlow::flow(_, sink) |
1513
sink.getLocation() = location and
1614
element = sink.toString() and
1715
value = ""

0 commit comments

Comments
 (0)