Skip to content

Commit 9d3863e

Browse files
committed
Ruby: Rely on built-in hash-flow in clear text storage query
1 parent ae10e6e commit 9d3863e

File tree

5 files changed

+45
-31
lines changed

5 files changed

+45
-31
lines changed

ruby/ql/lib/codeql/ruby/security/CleartextLoggingCustomizations.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module CleartextLogging {
2626
class Sanitizer = CleartextSources::Sanitizer;
2727

2828
/** Holds if `nodeFrom` taints `nodeTo`. */
29-
predicate isAdditionalTaintStep = CleartextSources::isAdditionalTaintStep/2;
29+
predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { none() }
3030

3131
/**
3232
* A data flow sink for cleartext logging of sensitive information.

ruby/ql/lib/codeql/ruby/security/CleartextStorageCustomizations.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module CleartextStorage {
2626
class Sanitizer = CleartextSources::Sanitizer;
2727

2828
/** Holds if `nodeFrom` taints `nodeTo`. */
29-
predicate isAdditionalTaintStep = CleartextSources::isAdditionalTaintStep/2;
29+
predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { none() }
3030

3131
/**
3232
* A data flow sink for cleartext storage of sensitive information.

ruby/ql/lib/codeql/ruby/security/internal/CleartextSources.qll

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -153,23 +153,21 @@ module CleartextSources {
153153
}
154154

155155
/**
156-
* A write to a hash entry with a value that may contain password information.
156+
* A value written to a hash entry with a key that may contain password information.
157157
*/
158158
private class HashKeyWritePasswordSource extends Source {
159159
private string name;
160160
private DataFlow::ExprNode recv;
161161

162162
HashKeyWritePasswordSource() {
163-
exists(DataFlow::Node val |
163+
exists(DataFlow::CallNode writeNode |
164164
name.regexpMatch(maybePassword()) and
165165
not nameIsNotSensitive(name) and
166166
// avoid safe values assigned to presumably unsafe names
167-
not val instanceof NonCleartextPassword and
168-
(
169-
// hash[name] = val
170-
hashKeyWrite(this, name, val) and
171-
recv = this.(DataFlow::CallNode).getReceiver()
172-
)
167+
not this instanceof NonCleartextPassword and
168+
// hash[name] = val
169+
hashKeyWrite(writeNode, name, this) and
170+
recv = writeNode.getReceiver()
173171
)
174172
}
175173

@@ -188,23 +186,21 @@ module CleartextSources {
188186
}
189187

190188
/**
191-
* A hash literal with an entry that may contain a password
189+
* An entry into a hash literal that may contain a password
192190
*/
193191
private class HashLiteralPasswordSource extends Source {
194192
private string name;
195193

196194
HashLiteralPasswordSource() {
197-
exists(DataFlow::Node val, CfgNodes::ExprNodes::HashLiteralCfgNode lit |
195+
exists(CfgNodes::ExprNodes::HashLiteralCfgNode lit |
198196
name.regexpMatch(maybePassword()) and
199197
not nameIsNotSensitive(name) and
200198
// avoid safe values assigned to presumably unsafe names
201-
not val instanceof NonCleartextPassword and
199+
not this instanceof NonCleartextPassword and
202200
// hash = { name: val }
203-
exists(CfgNodes::ExprNodes::PairCfgNode p |
204-
this.asExpr() = lit and p = lit.getAKeyValuePair()
205-
|
201+
exists(CfgNodes::ExprNodes::PairCfgNode p | p = lit.getAKeyValuePair() |
206202
p.getKey().getConstantValue().getStringlikeValue() = name and
207-
p.getValue() = val.asExpr()
203+
p.getValue() = this.asExpr()
208204
)
209205
)
210206
}
@@ -261,7 +257,7 @@ module CleartextSources {
261257
}
262258

263259
/** Holds if `nodeFrom` taints `nodeTo`. */
264-
predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
260+
deprecated predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
265261
exists(string name, ElementReference ref, LocalVariable hashVar |
266262
// from `hsh[password] = "changeme"` to a `hsh[password]` read
267263
nodeFrom.(HashKeyWritePasswordSource).getName() = name and

ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.expected

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ edges
1010
| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:23:33:23:40 | password |
1111
| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:26:18:26:34 | "pw: #{...}" |
1212
| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:28:26:28:33 | password |
13-
| logging.rb:30:8:30:55 | call to [] : | logging.rb:38:20:38:23 | hsh1 : |
14-
| logging.rb:30:8:30:55 | call to [] : | logging.rb:44:20:44:23 | hsh1 : |
15-
| logging.rb:34:1:34:15 | call to []= : | logging.rb:40:20:40:34 | ...[...] |
16-
| logging.rb:38:20:38:23 | hsh1 : | logging.rb:38:20:38:34 | ...[...] |
17-
| logging.rb:44:20:44:23 | hsh1 : | logging.rb:44:20:44:29 | ...[...] |
13+
| logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" : | logging.rb:38:20:38:23 | hsh1 [element :password] : |
14+
| logging.rb:34:1:34:4 | [post] hsh2 [element :password] : | logging.rb:40:20:40:23 | hsh2 [element :password] : |
15+
| logging.rb:34:1:34:4 | [post] hsh2 [element :password] : | logging.rb:42:20:42:23 | hsh3 [element :password] : |
16+
| logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" : | logging.rb:34:1:34:4 | [post] hsh2 [element :password] : |
17+
| logging.rb:38:20:38:23 | hsh1 [element :password] : | logging.rb:38:20:38:34 | ...[...] |
18+
| logging.rb:40:20:40:23 | hsh2 [element :password] : | logging.rb:40:20:40:34 | ...[...] |
19+
| logging.rb:42:20:42:23 | hsh3 [element :password] : | logging.rb:42:20:42:34 | ...[...] |
1820
| logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" : | logging.rb:68:35:68:65 | password_masked_ineffective_sub : |
1921
| logging.rb:65:38:65:71 | "ca497451f5e883662fb1a37bc9ec7838" : | logging.rb:78:20:78:53 | password_masked_ineffective_sub_ex |
2022
| logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" : | logging.rb:70:36:70:67 | password_masked_ineffective_gsub : |
@@ -39,13 +41,15 @@ nodes
3941
| logging.rb:23:33:23:40 | password | semmle.label | password |
4042
| logging.rb:26:18:26:34 | "pw: #{...}" | semmle.label | "pw: #{...}" |
4143
| logging.rb:28:26:28:33 | password | semmle.label | password |
42-
| logging.rb:30:8:30:55 | call to [] : | semmle.label | call to [] : |
43-
| logging.rb:34:1:34:15 | call to []= : | semmle.label | call to []= : |
44-
| logging.rb:38:20:38:23 | hsh1 : | semmle.label | hsh1 : |
44+
| logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" : | semmle.label | "aec5058e61f7f122998b1a30ee2c66b6" : |
45+
| logging.rb:34:1:34:4 | [post] hsh2 [element :password] : | semmle.label | [post] hsh2 [element :password] : |
46+
| logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" : | semmle.label | "beeda625d7306b45784d91ea0336e201" : |
47+
| logging.rb:38:20:38:23 | hsh1 [element :password] : | semmle.label | hsh1 [element :password] : |
4548
| logging.rb:38:20:38:34 | ...[...] | semmle.label | ...[...] |
49+
| logging.rb:40:20:40:23 | hsh2 [element :password] : | semmle.label | hsh2 [element :password] : |
4650
| logging.rb:40:20:40:34 | ...[...] | semmle.label | ...[...] |
47-
| logging.rb:44:20:44:23 | hsh1 : | semmle.label | hsh1 : |
48-
| logging.rb:44:20:44:29 | ...[...] | semmle.label | ...[...] |
51+
| logging.rb:42:20:42:23 | hsh3 [element :password] : | semmle.label | hsh3 [element :password] : |
52+
| logging.rb:42:20:42:34 | ...[...] | semmle.label | ...[...] |
4953
| logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" : | semmle.label | "ca497451f5e883662fb1a37bc9ec7838" : |
5054
| logging.rb:65:38:65:71 | "ca497451f5e883662fb1a37bc9ec7838" : | semmle.label | "ca497451f5e883662fb1a37bc9ec7838" : |
5155
| logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" : | semmle.label | "a7e3747b19930d4f4b8181047194832f" : |
@@ -75,9 +79,9 @@ subpaths
7579
| logging.rb:23:33:23:40 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:23:33:23:40 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password |
7680
| logging.rb:26:18:26:34 | "pw: #{...}" | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:26:18:26:34 | "pw: #{...}" | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password |
7781
| logging.rb:28:26:28:33 | password | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:28:26:28:33 | password | This logs sensitive data returned by $@ as clear text. | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" | an assignment to password |
78-
| logging.rb:38:20:38:34 | ...[...] | logging.rb:30:8:30:55 | call to [] : | logging.rb:38:20:38:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:30:8:30:55 | call to [] | a write to password |
79-
| logging.rb:40:20:40:34 | ...[...] | logging.rb:34:1:34:15 | call to []= : | logging.rb:40:20:40:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:34:1:34:15 | call to []= | a write to password |
80-
| logging.rb:44:20:44:29 | ...[...] | logging.rb:30:8:30:55 | call to [] : | logging.rb:44:20:44:29 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:30:8:30:55 | call to [] | a write to password |
82+
| logging.rb:38:20:38:34 | ...[...] | logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" : | logging.rb:38:20:38:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" | a write to password |
83+
| logging.rb:40:20:40:34 | ...[...] | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" : | logging.rb:40:20:40:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" | a write to password |
84+
| logging.rb:42:20:42:34 | ...[...] | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" : | logging.rb:42:20:42:34 | ...[...] | This logs sensitive data returned by $@ as clear text. | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" | a write to password |
8185
| logging.rb:74:20:74:50 | password_masked_ineffective_sub | logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" : | logging.rb:74:20:74:50 | password_masked_ineffective_sub | This logs sensitive data returned by $@ as clear text. | logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" | an assignment to password_masked_ineffective_sub |
8286
| logging.rb:74:20:74:50 | password_masked_ineffective_sub | logging.rb:68:35:68:88 | call to sub : | logging.rb:74:20:74:50 | password_masked_ineffective_sub | This logs sensitive data returned by $@ as clear text. | logging.rb:68:35:68:88 | call to sub | an assignment to password_masked_ineffective_sub |
8387
| logging.rb:76:20:76:51 | password_masked_ineffective_gsub | logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" : | logging.rb:76:20:76:51 | password_masked_ineffective_gsub | This logs sensitive data returned by $@ as clear text. | logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" | an assignment to password_masked_ineffective_gsub |

0 commit comments

Comments
 (0)