@@ -17,6 +17,7 @@ class MessageDigest extends RefType {
17
17
MessageDigest ( ) { this .hasQualifiedName ( "java.security" , "MessageDigest" ) }
18
18
}
19
19
20
+ /** The method call `MessageDigest.getInstance(...)` */
20
21
class MDConstructor extends StaticMethodAccess {
21
22
MDConstructor ( ) {
22
23
exists ( Method m | m = this .getMethod ( ) |
@@ -57,46 +58,35 @@ class MDHashMethodAccess extends MethodAccess {
57
58
string getPasswordRegex ( ) { result = "(?i).*pass(wd|word|code|phrase).*" }
58
59
59
60
/** Finds variables that hold password information judging by their names. */
60
- class PasswordVarExpr extends Expr {
61
+ class PasswordVarExpr extends VarAccess {
61
62
PasswordVarExpr ( ) {
62
- this .( VarAccess ) .getVariable ( ) .getName ( ) .toLowerCase ( ) .regexpMatch ( getPasswordRegex ( ) ) and
63
- not this .( VarAccess ) .getVariable ( ) .getName ( ) .toLowerCase ( ) .matches ( "%hash%" ) // Exclude variable names such as `passwordHash` since their values were already hashed
63
+ exists ( string name | name = this .getVariable ( ) .getName ( ) .toLowerCase ( ) |
64
+ name .regexpMatch ( getPasswordRegex ( ) ) and not name .matches ( "%hash%" ) // Exclude variable names such as `passwordHash` since their values were already hashed
65
+ )
64
66
}
65
67
}
66
68
67
69
/** Holds if `Expr` e is a direct or indirect operand of `ae`. */
68
- predicate hasAddExpr ( AddExpr ae , Expr e ) { ae .getAnOperand + ( ) = e }
70
+ predicate hasAddExprAncestor ( AddExpr ae , Expr e ) { ae .getAnOperand + ( ) = e }
69
71
70
- /** Holds if `MethodAccess` ma has a flow to another `MDHashMethodAccess` call. */
71
- predicate hasAnotherHashCall ( MethodAccess ma ) {
72
- exists ( MDHashMethodAccess ma2 , DataFlow :: Node node1 , DataFlow :: Node node2 |
72
+ /** Holds if `MDHashMethodAccess ma` is a second `MDHashMethodAccess` call by the same object . */
73
+ predicate hasAnotherHashCall ( MDHashMethodAccess ma ) {
74
+ exists ( MDHashMethodAccess ma2 |
73
75
ma2 != ma and
74
- node1 .asExpr ( ) = ma .getAChildExpr ( ) and
75
- node2 .asExpr ( ) = ma2 .getAChildExpr ( ) and
76
- (
77
- TaintTracking2:: localTaint ( node1 , node2 ) or
78
- TaintTracking2:: localTaint ( node2 , node1 )
79
- )
76
+ ma2 .getQualifier ( ) = ma .getQualifier ( ) .( VarAccess ) .getVariable ( ) .getAnAccess ( )
80
77
)
81
78
}
82
79
83
80
/** Holds if `MethodAccess` ma is a hashing call without a sibling node making another hashing call. */
84
81
predicate isSingleHashMethodCall ( MDHashMethodAccess ma ) { not hasAnotherHashCall ( ma ) }
85
82
86
83
/** Holds if `MethodAccess` ma is invoked by `MethodAccess` ma2 either directly or indirectly. */
87
- predicate hasParentCall ( MethodAccess ma2 , MethodAccess ma ) {
88
- ma .getCaller ( ) = ma2 .getMethod ( )
89
- or
90
- exists ( MethodAccess ma3 |
91
- ma .getCaller ( ) = ma3 .getMethod ( ) and
92
- hasParentCall ( ma2 , ma3 )
93
- )
94
- }
84
+ predicate hasParentCall ( MethodAccess ma2 , MethodAccess ma ) { ma .getCaller ( ) = ma2 .getMethod ( ) }
95
85
96
86
/** Holds if `MethodAccess` is a single hashing call that is not invoked by a wrapper method. */
97
87
predicate isSink ( MethodAccess ma ) {
98
88
isSingleHashMethodCall ( ma ) and
99
- not exists ( MethodAccess ma2 | hasParentCall ( ma2 , ma ) ) // Not invoked by a wrapper method which could invoke MDHashMethod in another call stack to reduce FPs
89
+ not hasParentCall ( _ , ma ) // Not invoked by a wrapper method which could invoke MDHashMethod in another call stack. This reduces FPs.
100
90
}
101
91
102
92
/** Sink of hashing calls. */
@@ -131,9 +121,9 @@ class HashWithoutSaltConfiguration extends TaintTracking::Configuration {
131
121
ma .getArgument ( 0 ) = node .asExpr ( )
132
122
) // System.arraycopy(password.getBytes(), ...)
133
123
or
134
- exists ( AddExpr e | hasAddExpr ( e , node .asExpr ( ) ) ) // password+salt
124
+ exists ( AddExpr e | hasAddExprAncestor ( e , node .asExpr ( ) ) ) // password+salt
135
125
or
136
- exists ( ConditionalExpr ce | ce = node .asExpr ( ) ) // useSalt?password+":"+salt:password
126
+ exists ( ConditionalExpr ce | ce . getAChildExpr ( ) = node .asExpr ( ) ) // useSalt?password+":"+salt:password
137
127
or
138
128
exists ( MethodAccess ma |
139
129
ma .getMethod ( ) .getDeclaringType ( ) .hasQualifiedName ( "java.lang" , "StringBuilder" ) and
@@ -143,7 +133,7 @@ class HashWithoutSaltConfiguration extends TaintTracking::Configuration {
143
133
or
144
134
exists ( MethodAccess ma |
145
135
ma .getQualifier ( ) .( VarAccess ) .getVariable ( ) .getType ( ) instanceof Interface and
146
- ma .getAnArgument ( ) = node .asExpr ( ) // Method access of interface type variables requires runtime determination
136
+ ma .getAnArgument ( ) = node .asExpr ( ) // Method access of interface type variables requires runtime determination thus not handled
147
137
)
148
138
}
149
139
}
0 commit comments