@@ -17,6 +17,7 @@ class MessageDigest extends RefType {
1717 MessageDigest ( ) { this .hasQualifiedName ( "java.security" , "MessageDigest" ) }
1818}
1919
20+ /** The method call `MessageDigest.getInstance(...)` */
2021class MDConstructor extends StaticMethodAccess {
2122 MDConstructor ( ) {
2223 exists ( Method m | m = this .getMethod ( ) |
@@ -57,46 +58,35 @@ class MDHashMethodAccess extends MethodAccess {
5758string getPasswordRegex ( ) { result = "(?i).*pass(wd|word|code|phrase).*" }
5859
5960/** Finds variables that hold password information judging by their names. */
60- class PasswordVarExpr extends Expr {
61+ class PasswordVarExpr extends VarAccess {
6162 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+ )
6466 }
6567}
6668
6769/** 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 }
6971
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 |
7375 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 ( )
8077 )
8178}
8279
8380/** Holds if `MethodAccess` ma is a hashing call without a sibling node making another hashing call. */
8481predicate isSingleHashMethodCall ( MDHashMethodAccess ma ) { not hasAnotherHashCall ( ma ) }
8582
8683/** 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 ( ) }
9585
9686/** Holds if `MethodAccess` is a single hashing call that is not invoked by a wrapper method. */
9787predicate isSink ( MethodAccess ma ) {
9888 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.
10090}
10191
10292/** Sink of hashing calls. */
@@ -131,9 +121,9 @@ class HashWithoutSaltConfiguration extends TaintTracking::Configuration {
131121 ma .getArgument ( 0 ) = node .asExpr ( )
132122 ) // System.arraycopy(password.getBytes(), ...)
133123 or
134- exists ( AddExpr e | hasAddExpr ( e , node .asExpr ( ) ) ) // password+salt
124+ exists ( AddExpr e | hasAddExprAncestor ( e , node .asExpr ( ) ) ) // password+salt
135125 or
136- exists ( ConditionalExpr ce | ce = node .asExpr ( ) ) // useSalt?password+":"+salt:password
126+ exists ( ConditionalExpr ce | ce . getAChildExpr ( ) = node .asExpr ( ) ) // useSalt?password+":"+salt:password
137127 or
138128 exists ( MethodAccess ma |
139129 ma .getMethod ( ) .getDeclaringType ( ) .hasQualifiedName ( "java.lang" , "StringBuilder" ) and
@@ -143,7 +133,7 @@ class HashWithoutSaltConfiguration extends TaintTracking::Configuration {
143133 or
144134 exists ( MethodAccess ma |
145135 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
147137 )
148138 }
149139}
0 commit comments