@@ -92,27 +92,33 @@ module CleartextLogging {
92
92
}
93
93
94
94
/**
95
- * Gets the name of a method that would be falsely marked as non-sensitive
96
- * by `notSensitiveRegexp` .
95
+ * Holds if ` name` is for a method or variable that appears, syntactically, to
96
+ * not be sensitive .
97
97
*/
98
- private predicate nonSensitiveMethodNameExclusion ( string name ) { name = [ "[]" , "[]=" ] }
98
+ bindingset [ name]
99
+ private predicate nameIsNotSensitive ( string name ) {
100
+ name .regexpMatch ( notSensitiveRegexp ( ) ) and
101
+ // By default `notSensitiveRegexp()` includes some false positives for
102
+ // common ruby method names that are not necessarily non-sensitive.
103
+ // We explicitly exclude element references, element assignments, and
104
+ // mutation methods.
105
+ not name = [ "[]" , "[]=" ] and
106
+ not name .suffix ( 1 ) = "!"
107
+ }
99
108
100
109
/**
101
110
* A call that might obfuscate a password, for example through hashing.
102
111
*/
103
112
private class ObfuscatorCall extends Sanitizer , DataFlow:: CallNode {
104
- ObfuscatorCall ( ) {
105
- this .getMethodName ( ) .regexpMatch ( notSensitiveRegexp ( ) ) and
106
- not nonSensitiveMethodNameExclusion ( this .getMethodName ( ) )
107
- }
113
+ ObfuscatorCall ( ) { nameIsNotSensitive ( this .getMethodName ( ) ) }
108
114
}
109
115
110
116
/**
111
117
* A data flow node that does not contain a clear-text password, according to its syntactic name.
112
118
*/
113
119
private class NameGuidedNonCleartextPassword extends NonCleartextPassword {
114
120
NameGuidedNonCleartextPassword ( ) {
115
- exists ( string name | name . regexpMatch ( notSensitiveRegexp ( ) ) |
121
+ exists ( string name | nameIsNotSensitive ( name ) |
116
122
// accessing a non-sensitive variable
117
123
this .asExpr ( ) .getExpr ( ) .( VariableReadAccess ) .getVariable ( ) .getName ( ) = name
118
124
or
@@ -125,8 +131,7 @@ module CleartextLogging {
125
131
.getStringOrSymbol ( ) = name
126
132
or
127
133
// calling a non-sensitive method
128
- this .( DataFlow:: CallNode ) .getMethodName ( ) = name and
129
- not nonSensitiveMethodNameExclusion ( name )
134
+ this .( DataFlow:: CallNode ) .getMethodName ( ) = name
130
135
)
131
136
or
132
137
// avoid i18n strings
@@ -175,7 +180,7 @@ module CleartextLogging {
175
180
HashKeyWritePasswordSource ( ) {
176
181
exists ( DataFlow:: Node val |
177
182
name .regexpMatch ( maybePassword ( ) ) and
178
- not name . regexpMatch ( notSensitiveRegexp ( ) ) and
183
+ not nameIsNotSensitive ( name ) and
179
184
// avoid safe values assigned to presumably unsafe names
180
185
not val instanceof NonCleartextPassword and
181
186
(
0 commit comments