Skip to content

Commit 3bda0b9

Browse files
committed
C#: Re-factor HardcodedCredentials to use the new API.
1 parent d94b11b commit 3bda0b9

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

csharp/ql/lib/semmle/code/csharp/security/dataflow/HardcodedCredentialsQuery.qll

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,11 @@ abstract class Sink extends DataFlow::ExprNode {
3838
abstract class Sanitizer extends DataFlow::ExprNode { }
3939

4040
/**
41+
* DEPRECATED: Use `HardcodedCredentials` instead.
42+
*
4143
* A taint-tracking configuration for hard coded credentials.
4244
*/
43-
class TaintTrackingConfiguration extends TaintTracking::Configuration {
45+
deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration {
4446
TaintTrackingConfiguration() { this = "HardcodedCredentials" }
4547

4648
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -75,6 +77,56 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
7577
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
7678
}
7779

80+
/**
81+
* A taint-tracking configuration for hard coded credentials.
82+
*/
83+
private module HardcodedCredentialsConfig implements DataFlow::ConfigSig {
84+
predicate isSource(DataFlow::Node source) { source instanceof Source }
85+
86+
predicate isSink(DataFlow::Node sink) {
87+
sink instanceof Sink and
88+
// Ignore values that are ultimately returned by mocks, as they don't represent "real"
89+
// credentials.
90+
not any(ReturnedByMockObject mock).getAMemberInitializationValue() = sink.asExpr() and
91+
not any(ReturnedByMockObject mock).getAnArgument() = sink.asExpr()
92+
}
93+
94+
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
95+
}
96+
97+
/**
98+
* A taint-tracking module for hard coded credentials.
99+
*/
100+
module HardcodedCredentials {
101+
import TaintTracking::Global<HardcodedCredentialsConfig> as Super
102+
import Super
103+
104+
/**
105+
* Holds if data can flow from `source` to `sink`.
106+
*
107+
* The corresponding paths are generated from the end-points and the graph
108+
* included in the module `PathGraph`.
109+
*/
110+
predicate flowPath(HardcodedCredentials::PathNode source, HardcodedCredentials::PathNode sink) {
111+
Super::flowPath(source, sink) and
112+
// Exclude hard-coded credentials in tests if they only flow to calls to methods with a name
113+
// like "Add*" "Create*" or "Update*". The rationale is that hard-coded credentials within
114+
// tests that are only used for creating or setting values within tests are unlikely to
115+
// represent credentials to some accessible system.
116+
not (
117+
source.getNode().asExpr().getFile() instanceof TestFile and
118+
exists(MethodCall createOrAddCall, string createOrAddMethodName |
119+
createOrAddMethodName.matches("Update%") or
120+
createOrAddMethodName.matches("Create%") or
121+
createOrAddMethodName.matches("Add%")
122+
|
123+
createOrAddCall.getTarget().hasName(createOrAddMethodName) and
124+
createOrAddCall.getAnArgument() = sink.getNode().asExpr()
125+
)
126+
)
127+
}
128+
}
129+
78130
/**
79131
* A string literal that is not empty.
80132
*/

csharp/ql/src/Security Features/CWE-798/HardcodedCredentials.ql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@
1414

1515
import csharp
1616
import semmle.code.csharp.security.dataflow.HardcodedCredentialsQuery
17-
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
17+
import HardcodedCredentials::PathGraph
1818

1919
from
20-
TaintTrackingConfiguration c, Source source, Sink sink, DataFlow::PathNode sourcePath,
21-
DataFlow::PathNode sinkPath, string value
20+
Source source, Sink sink, HardcodedCredentials::PathNode sourcePath,
21+
HardcodedCredentials::PathNode sinkPath, string value
2222
where
2323
source = sourcePath.getNode() and
2424
sink = sinkPath.getNode() and
25-
c.hasFlowPath(sourcePath, sinkPath) and
25+
HardcodedCredentials::flowPath(sourcePath, sinkPath) and
2626
// Print the source value if it's available
2727
if exists(source.asExpr().getValue())
2828
then value = "The hard-coded value \"" + source.asExpr().getValue() + "\""

0 commit comments

Comments
 (0)