@@ -38,9 +38,11 @@ abstract class Sink extends DataFlow::ExprNode {
3838abstract 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 */
0 commit comments