@@ -9,6 +9,7 @@ private import codeql.ruby.DataFlow
9
9
private import codeql.ruby.TaintTracking:: TaintTracking
10
10
private import codeql.ruby.dataflow.RemoteFlowSources
11
11
private import SensitiveDataHeuristics:: HeuristicNames
12
+ private import SensitiveDataHeuristics
12
13
private import codeql.ruby.CFG
13
14
private import codeql.ruby.dataflow.SSA
14
15
@@ -92,17 +93,17 @@ module CleartextSources {
92
93
}
93
94
94
95
/**
95
- * A call that might obfuscate a password , for example through hashing.
96
+ * A call that might obfuscate sensitive data , for example through hashing.
96
97
*/
97
98
private class ObfuscatorCall extends Sanitizer , DataFlow:: CallNode {
98
99
ObfuscatorCall ( ) { nameIsNotSensitive ( this .getMethodName ( ) ) }
99
100
}
100
101
101
102
/**
102
- * A data flow node that does not contain a clear-text password , according to its syntactic name.
103
+ * A data flow node that does not contain clear-text sensitive data , according to its syntactic name.
103
104
*/
104
- private class NameGuidedNonCleartextPassword extends NonCleartextPassword {
105
- NameGuidedNonCleartextPassword ( ) {
105
+ private class NameGuidedNonCleartextSensitive extends NonCleartextSensitive {
106
+ NameGuidedNonCleartextSensitive ( ) {
106
107
exists ( string name | nameIsNotSensitive ( name ) |
107
108
// accessing a non-sensitive variable
108
109
this .asExpr ( ) .getExpr ( ) .( VariableReadAccess ) .getVariable ( ) .getName ( ) = name
@@ -129,18 +130,23 @@ module CleartextSources {
129
130
}
130
131
131
132
/**
132
- * A data flow node that receives flow that is not a clear-text password .
133
+ * A data flow node that receives flow that is not clear-text sensitive data .
133
134
*/
134
- class NonCleartextPasswordFlow extends NonCleartextPassword {
135
- NonCleartextPasswordFlow ( ) {
136
- any ( NonCleartextPassword other ) .( DataFlow:: LocalSourceNode ) .flowsTo ( this )
135
+ class NonCleartextSensitiveFlow extends NonCleartextSensitive {
136
+ NonCleartextSensitiveFlow ( ) {
137
+ any ( NonCleartextSensitive other ) .( DataFlow:: LocalSourceNode ) .flowsTo ( this )
137
138
}
138
139
}
139
140
140
141
/**
141
- * A data flow node that does not contain a clear-text password .
142
+ * DEPRECATED: Use NonCleartextSensitiveFlow instead .
142
143
*/
143
- abstract private class NonCleartextPassword extends DataFlow:: Node { }
144
+ deprecated class NonCleartextPasswordFlow = NonCleartextSensitiveFlow ;
145
+
146
+ /**
147
+ * A data flow node that does not contain clear-text sensitive data.
148
+ */
149
+ abstract private class NonCleartextSensitive extends DataFlow:: Node { }
144
150
145
151
// `writeNode` assigns pair with key `name` to `val`
146
152
private predicate hashKeyWrite ( DataFlow:: CallNode writeNode , string name , DataFlow:: Node val ) {
@@ -153,18 +159,19 @@ module CleartextSources {
153
159
}
154
160
155
161
/**
156
- * A value written to a hash entry with a key that may contain password information.
162
+ * A value written to a hash entry with a key that may contain sensitive information.
157
163
*/
158
- private class HashKeyWritePasswordSource extends Source {
164
+ private class HashKeyWriteSensitiveSource extends Source {
159
165
private string name ;
160
166
private DataFlow:: ExprNode recv ;
161
167
162
- HashKeyWritePasswordSource ( ) {
163
- exists ( DataFlow:: CallNode writeNode |
164
- name .regexpMatch ( maybePassword ( ) ) and
168
+ HashKeyWriteSensitiveSource ( ) {
169
+ exists ( DataFlow:: CallNode writeNode , SensitiveDataClassification classification |
170
+ nameIndicatesSensitiveData ( name , classification ) and
171
+ not classification = SensitiveDataClassification:: id ( ) and
165
172
not nameIsNotSensitive ( name ) and
166
173
// avoid safe values assigned to presumably unsafe names
167
- not this instanceof NonCleartextPassword and
174
+ not this instanceof NonCleartextSensitive and
168
175
// hash[name] = val
169
176
hashKeyWrite ( writeNode , name , this ) and
170
177
recv = writeNode .getReceiver ( )
@@ -177,7 +184,7 @@ module CleartextSources {
177
184
string getName ( ) { result = name }
178
185
179
186
/**
180
- * Gets the name of the hash variable that this password source is assigned
187
+ * Gets the name of the hash variable that this sensitive source is assigned
181
188
* to, if applicable.
182
189
*/
183
190
LocalVariable getVariable ( ) {
@@ -186,17 +193,20 @@ module CleartextSources {
186
193
}
187
194
188
195
/**
189
- * An entry into a hash literal that may contain a password
196
+ * An entry into a hash literal that may contain sensitive data
190
197
*/
191
- private class HashLiteralPasswordSource extends Source {
198
+ private class HashLiteralSensitiveSource extends Source {
192
199
private string name ;
193
200
194
- HashLiteralPasswordSource ( ) {
195
- exists ( CfgNodes:: ExprNodes:: HashLiteralCfgNode lit |
196
- name .regexpMatch ( maybePassword ( ) ) and
201
+ HashLiteralSensitiveSource ( ) {
202
+ exists (
203
+ CfgNodes:: ExprNodes:: HashLiteralCfgNode lit , SensitiveDataClassification classification
204
+ |
205
+ nameIndicatesSensitiveData ( name , classification ) and
206
+ not classification = SensitiveDataClassification:: id ( ) and
197
207
not nameIsNotSensitive ( name ) and
198
208
// avoid safe values assigned to presumably unsafe names
199
- not this instanceof NonCleartextPassword and
209
+ not this instanceof NonCleartextSensitive and
200
210
// hash = { name: val }
201
211
exists ( CfgNodes:: ExprNodes:: PairCfgNode p | p = lit .getAKeyValuePair ( ) |
202
212
p .getKey ( ) .getConstantValue ( ) .getStringlikeValue ( ) = name and
@@ -208,36 +218,42 @@ module CleartextSources {
208
218
override string describe ( ) { result = "a write to " + name }
209
219
}
210
220
211
- /** An assignment that may assign a password to a variable */
212
- private class AssignPasswordVariableSource extends Source {
221
+ /** An assignment that may assign sensitive data to a variable */
222
+ private class AssignSensitiveVariableSource extends Source {
213
223
string name ;
214
224
215
- AssignPasswordVariableSource ( ) {
216
- // avoid safe values assigned to presumably unsafe names
217
- not this instanceof NonCleartextPassword and
218
- name .regexpMatch ( maybePassword ( ) ) and
219
- not nameIsNotSensitive ( name ) and
220
- exists ( Assignment a |
221
- this .asExpr ( ) .getExpr ( ) = a .getRightOperand ( ) and
222
- a .getLeftOperand ( ) .getAVariable ( ) .getName ( ) = name
225
+ AssignSensitiveVariableSource ( ) {
226
+ exists ( SensitiveDataClassification classification |
227
+ // avoid safe values assigned to presumably unsafe names
228
+ not this instanceof NonCleartextSensitive and
229
+ nameIndicatesSensitiveData ( name , classification ) and
230
+ not classification = SensitiveDataClassification:: id ( ) and
231
+ not nameIsNotSensitive ( name ) and
232
+ exists ( Assignment a |
233
+ this .asExpr ( ) .getExpr ( ) = a .getRightOperand ( ) and
234
+ a .getLeftOperand ( ) .getAVariable ( ) .getName ( ) = name
235
+ )
223
236
)
224
237
}
225
238
226
239
override string describe ( ) { result = "an assignment to " + name }
227
240
}
228
241
229
- /** A parameter that may contain a password . */
230
- private class ParameterPasswordSource extends Source {
242
+ /** A parameter that may contain sensitive data . */
243
+ private class ParameterSensitiveSource extends Source {
231
244
private string name ;
232
245
233
- ParameterPasswordSource ( ) {
234
- name .regexpMatch ( maybePassword ( ) ) and
235
- not nameIsNotSensitive ( name ) and
236
- not this instanceof NonCleartextPassword and
237
- exists ( Parameter p , LocalVariable v |
238
- v = p .getAVariable ( ) and
239
- v .getName ( ) = name and
240
- this .asExpr ( ) .getExpr ( ) = v .getAnAccess ( )
246
+ ParameterSensitiveSource ( ) {
247
+ exists ( SensitiveDataClassification classification |
248
+ nameIndicatesSensitiveData ( name , classification ) and
249
+ not classification = SensitiveDataClassification:: id ( ) and
250
+ not nameIsNotSensitive ( name ) and
251
+ not this instanceof NonCleartextSensitive and
252
+ exists ( Parameter p , LocalVariable v |
253
+ v = p .getAVariable ( ) and
254
+ v .getName ( ) = name and
255
+ this .asExpr ( ) .getExpr ( ) = v .getAnAccess ( )
256
+ )
241
257
)
242
258
}
243
259
@@ -260,10 +276,10 @@ module CleartextSources {
260
276
deprecated predicate isAdditionalTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
261
277
exists ( string name , ElementReference ref , LocalVariable hashVar |
262
278
// from `hsh[password] = "changeme"` to a `hsh[password]` read
263
- nodeFrom .( HashKeyWritePasswordSource ) .getName ( ) = name and
279
+ nodeFrom .( HashKeyWriteSensitiveSource ) .getName ( ) = name and
264
280
nodeTo .asExpr ( ) .getExpr ( ) = ref and
265
281
ref .getArgument ( 0 ) .getConstantValue ( ) .getStringlikeValue ( ) = name and
266
- nodeFrom .( HashKeyWritePasswordSource ) .getVariable ( ) = hashVar and
282
+ nodeFrom .( HashKeyWriteSensitiveSource ) .getVariable ( ) = hashVar and
267
283
ref .getReceiver ( ) .( VariableReadAccess ) .getVariable ( ) = hashVar and
268
284
nodeFrom .asExpr ( ) .getASuccessor * ( ) = nodeTo .asExpr ( )
269
285
)
0 commit comments