@@ -55,29 +55,17 @@ class HashWithoutSaltConfiguration extends TaintTracking::Configuration {
5555
5656 override predicate isSink ( DataFlow:: Node sink ) {
5757 exists (
58- MethodAccess mua , MethodAccess mda // invoke `md.digest()` with only one call of `md. update(password)`, that is, without the call of `md.update(digest)`
58+ MethodAccess mua // invoke `md.update(password)` without the call of `md.update(digest)`
5959 |
6060 sink .asExpr ( ) = mua .getArgument ( 0 ) and
61- mua .getMethod ( ) instanceof MDUpdateMethod and // md.update(password)
62- mda .getMethod ( ) instanceof MDDigestMethod and
63- mda .getNumArgument ( ) = 0 and // md.digest()
64- mda .getQualifier ( ) = mua .getQualifier ( ) .( VarAccess ) .getVariable ( ) .getAnAccess ( ) and
65- not exists ( MethodAccess mua2 |
66- mua2 .getMethod ( ) instanceof MDUpdateMethod and // md.update(salt)
67- mua2 .getQualifier ( ) = mua .getQualifier ( ) .( VarAccess ) .getVariable ( ) .getAnAccess ( ) and
68- mua2 != mua
69- )
61+ mua .getMethod ( ) instanceof MDUpdateMethod // md.update(password)
7062 )
7163 or
7264 // invoke `md.digest(password)` without another call of `md.update(salt)`
7365 exists ( MethodAccess mda |
7466 sink .asExpr ( ) = mda .getArgument ( 0 ) and
7567 mda .getMethod ( ) instanceof MDDigestMethod and // md.digest(password)
76- mda .getNumArgument ( ) = 1 and
77- not exists ( MethodAccess mua |
78- mua .getMethod ( ) instanceof MDUpdateMethod and // md.update(salt)
79- mua .getQualifier ( ) = mda .getQualifier ( ) .( VarAccess ) .getVariable ( ) .getAnAccess ( )
80- )
68+ mda .getNumArgument ( ) = 1
8169 )
8270 }
8371
@@ -96,9 +84,37 @@ class HashWithoutSaltConfiguration extends TaintTracking::Configuration {
9684 ) // System.arraycopy(password.getBytes(), ...)
9785 or
9886 exists ( AddExpr e | node .asExpr ( ) = e .getAnOperand ( ) ) // password+salt
87+ or
88+ exists ( MethodAccess mua , MethodAccess ma |
89+ ma .getArgument ( 0 ) = node .asExpr ( ) and // Detect wrapper methods that invoke `md.update(salt)`
90+ ma != mua and
91+ (
92+ mua .getQualifier ( ) .( VarAccess ) .getVariable ( ) .getAnAccess ( ) = ma .getQualifier ( )
93+ or
94+ mua .getAnArgument ( ) .( VarAccess ) .getVariable ( ) .getAnAccess ( ) = ma .getQualifier ( )
95+ or
96+ mua .getQualifier ( ) .( VarAccess ) .getVariable ( ) .getAnAccess ( ) = ma .getAnArgument ( )
97+ or
98+ mua .getAnArgument ( ) .( VarAccess ) .getVariable ( ) .getAnAccess ( ) = ma .getAnArgument ( )
99+ ) and
100+ isMDUpdateCall ( mua .getMethod ( ) )
101+ )
99102 }
100103}
101104
105+ /** Holds if a method invokes `md.update(salt)`. */
106+ predicate isMDUpdateCall ( Callable caller ) {
107+ caller instanceof MDUpdateMethod
108+ or
109+ exists ( Callable callee |
110+ caller .polyCalls ( callee ) and
111+ (
112+ callee instanceof MDUpdateMethod or
113+ isMDUpdateCall ( callee )
114+ )
115+ )
116+ }
117+
102118from DataFlow:: PathNode source , DataFlow:: PathNode sink , HashWithoutSaltConfiguration c
103119where c .hasFlowPath ( source , sink )
104120select sink .getNode ( ) , source , sink , "$@ is hashed without a salt." , source .getNode ( ) ,
0 commit comments