Skip to content

Commit e80faa0

Browse files
committed
Fix rb/reflected-xss flow from helper method return values
1 parent 35da921 commit e80faa0

File tree

3 files changed

+21
-7
lines changed

3 files changed

+21
-7
lines changed

ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4552,3 +4552,13 @@ private predicate revPartialFlow(
45524552
sink.isRevSink() and
45534553
node.getASuccessor+() = sink
45544554
}
4555+
4556+
/**
4557+
* Holds if `n` is a return node from callable `c`.
4558+
*/
4559+
predicate nodeReturnedFrom(ReturnNodeExt n, DataFlowCallable c) {
4560+
exists(RetNodeEx ret |
4561+
n = ret.asNode() and
4562+
c = ret.getReturnPosition().getCallable()
4563+
)
4564+
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,15 +185,13 @@ module ReflectedXSS {
185185
// flow out of controller helper method into template
186186
exists(
187187
ErbFile template, ActionControllerHelperMethod helperMethod,
188-
CfgNodes::ExprNodes::MethodCallCfgNode helperMethodCall, ReturnStmt ret
188+
CfgNodes::ExprNodes::MethodCallCfgNode helperMethodCall
189189
|
190190
template = node2.getLocation().getFile() and
191191
helperMethod.getName() = helperMethodCall.getExpr().getMethodName() and
192192
helperMethod.getControllerClass() = getAssociatedControllerClass(template) and
193193
// `node1` is a returned value
194-
// TODO: we don't pick up implicit returns with this approach
195-
node1.asExpr().getExpr().getParent() = ret and
196-
ret.getParent+() = helperMethod and
194+
DataFlow::nodeReturnedFrom(node1, helperMethod) and
197195
node2.asExpr() = helperMethodCall
198196
)
199197
}

ql/test/query-tests/security/cwe-079/ReflectedXSS.expected

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
edges
2-
| app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params : | app/controllers/foo/bars_controller.rb:9:12:9:29 | ...[...] : |
3-
| app/controllers/foo/bars_controller.rb:9:12:9:29 | ...[...] : | app/views/foo/bars/show.html.erb:47:5:47:13 | call to user_name |
2+
| app/controllers/foo/bars_controller.rb:9:5:9:29 | return : | app/views/foo/bars/show.html.erb:47:5:47:13 | call to user_name |
3+
| app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params : | app/controllers/foo/bars_controller.rb:9:5:9:29 | return : |
4+
| app/controllers/foo/bars_controller.rb:13:5:13:37 | ... = ... : | app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo |
5+
| app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params : | app/controllers/foo/bars_controller.rb:13:5:13:37 | ... = ... : |
46
| app/controllers/foo/bars_controller.rb:17:21:17:26 | call to params : | app/controllers/foo/bars_controller.rb:17:21:17:36 | ...[...] : |
57
| app/controllers/foo/bars_controller.rb:17:21:17:36 | ...[...] : | app/views/foo/bars/show.html.erb:2:18:2:30 | @user_website |
68
| app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/controllers/foo/bars_controller.rb:19:22:19:23 | dt : |
@@ -17,8 +19,10 @@ edges
1719
| app/views/foo/bars/show.html.erb:54:29:54:34 | call to params : | app/views/foo/bars/show.html.erb:54:29:54:44 | ...[...] |
1820
| app/views/foo/bars/show.html.erb:57:13:57:18 | call to params : | app/views/foo/bars/show.html.erb:57:13:57:28 | ...[...] |
1921
nodes
22+
| app/controllers/foo/bars_controller.rb:9:5:9:29 | return : | semmle.label | return : |
2023
| app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params : | semmle.label | call to params : |
21-
| app/controllers/foo/bars_controller.rb:9:12:9:29 | ...[...] : | semmle.label | ...[...] : |
24+
| app/controllers/foo/bars_controller.rb:13:5:13:37 | ... = ... : | semmle.label | ... = ... : |
25+
| app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params : | semmle.label | call to params : |
2226
| app/controllers/foo/bars_controller.rb:17:21:17:26 | call to params : | semmle.label | call to params : |
2327
| app/controllers/foo/bars_controller.rb:17:21:17:36 | ...[...] : | semmle.label | ...[...] : |
2428
| app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | semmle.label | call to params : |
@@ -35,6 +39,7 @@ nodes
3539
| app/views/foo/bars/show.html.erb:44:64:44:87 | ... + ... : | semmle.label | ... + ... : |
3640
| app/views/foo/bars/show.html.erb:44:76:44:87 | call to display_text : | semmle.label | call to display_text : |
3741
| app/views/foo/bars/show.html.erb:47:5:47:13 | call to user_name | semmle.label | call to user_name |
42+
| app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo | semmle.label | call to user_name_memo |
3843
| app/views/foo/bars/show.html.erb:54:29:54:34 | call to params : | semmle.label | call to params : |
3944
| app/views/foo/bars/show.html.erb:54:29:54:44 | ...[...] | semmle.label | ...[...] |
4045
| app/views/foo/bars/show.html.erb:57:13:57:18 | call to params : | semmle.label | call to params : |
@@ -49,5 +54,6 @@ nodes
4954
| app/views/foo/bars/show.html.erb:36:3:36:14 | call to display_text | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/views/foo/bars/show.html.erb:36:3:36:14 | call to display_text | Cross-site scripting vulnerability due to $@. | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params | a user-provided value |
5055
| app/views/foo/bars/show.html.erb:41:3:41:16 | @instance_text | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/views/foo/bars/show.html.erb:41:3:41:16 | @instance_text | Cross-site scripting vulnerability due to $@. | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params | a user-provided value |
5156
| app/views/foo/bars/show.html.erb:47:5:47:13 | call to user_name | app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params : | app/views/foo/bars/show.html.erb:47:5:47:13 | call to user_name | Cross-site scripting vulnerability due to $@. | app/controllers/foo/bars_controller.rb:9:12:9:17 | call to params | a user-provided value |
57+
| app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo | app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params : | app/views/foo/bars/show.html.erb:51:5:51:18 | call to user_name_memo | Cross-site scripting vulnerability due to $@. | app/controllers/foo/bars_controller.rb:13:20:13:25 | call to params | a user-provided value |
5258
| app/views/foo/bars/show.html.erb:54:29:54:44 | ...[...] | app/views/foo/bars/show.html.erb:54:29:54:34 | call to params : | app/views/foo/bars/show.html.erb:54:29:54:44 | ...[...] | Cross-site scripting vulnerability due to $@. | app/views/foo/bars/show.html.erb:54:29:54:34 | call to params | a user-provided value |
5359
| app/views/foo/bars/show.html.erb:57:13:57:28 | ...[...] | app/views/foo/bars/show.html.erb:57:13:57:18 | call to params : | app/views/foo/bars/show.html.erb:57:13:57:28 | ...[...] | Cross-site scripting vulnerability due to $@. | app/views/foo/bars/show.html.erb:57:13:57:18 | call to params | a user-provided value |

0 commit comments

Comments
 (0)