Skip to content

Commit ad464ab

Browse files
committed
Ruby: Model more params accesses
1 parent 10aab81 commit ad464ab

File tree

5 files changed

+207
-6
lines changed

5 files changed

+207
-6
lines changed

ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,103 @@ private class ActionControllerParamsCall extends ActionControllerContextCall, Pa
161161
ActionControllerParamsCall() { this.getMethodName() = "params" }
162162
}
163163

164+
/** Modeling for `ActionDispatch::Request`. */
165+
private module Request {
166+
/**
167+
* A call to `request` from within a controller. This is an instance of
168+
* `ActionDispatch::Request`.
169+
*/
170+
private class RequestNode extends DataFlow::CallNode {
171+
RequestNode() {
172+
this.asExpr().getExpr() instanceof ActionControllerContextCall and
173+
this.getMethodName() = "request"
174+
}
175+
}
176+
177+
/**
178+
* A method call on `request`.
179+
*/
180+
private class RequestMethodCall extends DataFlow::CallNode {
181+
RequestMethodCall() {
182+
any(RequestNode r).(DataFlow::LocalSourceNode).flowsTo(this.getReceiver())
183+
}
184+
}
185+
186+
abstract private class RequestInputAccess extends RequestMethodCall,
187+
Http::Server::RequestInputAccess::Range {
188+
override string getSourceType() { result = "ActionDispatch::Request#" + this.getMethodName() }
189+
}
190+
191+
/**
192+
* A method call on `request` which returns request parameters.
193+
*/
194+
private class ParametersCall extends RequestInputAccess {
195+
ParametersCall() {
196+
this.getMethodName() =
197+
[
198+
"parameters", "params", "GET", "POST", "query_parameters", "request_parameters",
199+
"filtered_parameters"
200+
]
201+
}
202+
}
203+
204+
/** A method call on `request` which returns part or all of the request path. */
205+
private class PathCall extends RequestInputAccess {
206+
PathCall() {
207+
this.getMethodName() =
208+
["fullpath", "original_fullpath", "original_url", "url", "path", "filtered_path"]
209+
}
210+
}
211+
212+
/** A method call on `request` which returns a specific request header. */
213+
private class HeadersCall extends RequestInputAccess {
214+
HeadersCall() {
215+
this.getMethodName() =
216+
[
217+
"authorization", "script_name", "path_info", "user_agent", "referer", "referrer",
218+
"host_authority", "content_type", "host", "hostname", "accept_encoding",
219+
"accept_language", "if_none_match", "if_none_match_etags", "get_header", "fetch_header"
220+
]
221+
}
222+
}
223+
224+
// TODO: each_header
225+
/**
226+
* A method call on `request` which returns part or all of the host.
227+
* This can be influenced by headers such as Host and X-Forwarded-Host.
228+
*/
229+
private class HostCall extends RequestInputAccess {
230+
HostCall() {
231+
this.getMethodName() =
232+
[
233+
"authority", "host", "host_authority", "host_with_port", "hostname", "forwarded_for",
234+
"forwarded_host", "port", "forwarded_port"
235+
]
236+
}
237+
}
238+
239+
/**
240+
* A method call on `request` which is influenced by one or more request
241+
* headers.
242+
*/
243+
private class HeaderTaintedCall extends RequestInputAccess {
244+
HeaderTaintedCall() {
245+
this.getMethodName() =
246+
["media_type", "media_type", "media_type_params", "content_charset", "base_url"]
247+
}
248+
}
249+
250+
/** A method call on `request` which returns the request body. */
251+
private class BodyCall extends RequestInputAccess {
252+
BodyCall() { this.getMethodName() = ["body", "raw_post"] }
253+
}
254+
255+
/** A method call on `request` which returns the rack env. */
256+
private class EnvCall extends RequestInputAccess {
257+
EnvCall() { this.getMethodName() = ["env", "filtered_env"] }
258+
}
259+
}
260+
164261
/** A call to `render` from within a controller. */
165262
private class ActionControllerRenderCall extends ActionControllerContextCall, RenderCallImpl {
166263
ActionControllerRenderCall() { this.getMethodName() = "render" }

ruby/ql/test/library-tests/frameworks/ActionController.expected

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ actionControllerControllerClasses
55
| active_record/ActiveRecord.rb:66:1:98:3 | BazController |
66
| active_record/ActiveRecord.rb:100:1:108:3 | AnnotatedController |
77
| active_storage/active_storage.rb:39:1:45:3 | PostsController |
8-
| app/controllers/comments_controller.rb:1:1:7:3 | CommentsController |
8+
| app/controllers/comments_controller.rb:1:1:14:3 | CommentsController |
99
| app/controllers/foo/bars_controller.rb:3:1:46:3 | BarsController |
1010
| app/controllers/photos_controller.rb:1:1:4:3 | PhotosController |
1111
| app/controllers/posts_controller.rb:1:1:10:3 | PostsController |
@@ -59,8 +59,8 @@ actionControllerActionMethods
5959
| active_record/ActiveRecord.rb:101:3:103:5 | index |
6060
| active_record/ActiveRecord.rb:105:3:107:5 | unsafe_action |
6161
| active_storage/active_storage.rb:40:3:44:5 | create |
62-
| app/controllers/comments_controller.rb:2:3:3:5 | index |
63-
| app/controllers/comments_controller.rb:5:3:6:5 | show |
62+
| app/controllers/comments_controller.rb:2:3:10:5 | index |
63+
| app/controllers/comments_controller.rb:12:3:13:5 | show |
6464
| app/controllers/foo/bars_controller.rb:5:3:7:5 | index |
6565
| app/controllers/foo/bars_controller.rb:9:3:18:5 | show_debug |
6666
| app/controllers/foo/bars_controller.rb:20:3:24:5 | show |
@@ -222,6 +222,97 @@ paramsSources
222222
| app/controllers/foo/bars_controller.rb:21:21:21:26 | call to params |
223223
| app/controllers/foo/bars_controller.rb:22:10:22:15 | call to params |
224224
| app/views/foo/bars/show.html.erb:5:9:5:14 | call to params |
225+
httpInputAccesses
226+
| action_controller/params_flow.rb:3:10:3:15 | call to params | ActionController::Metal#params |
227+
| action_controller/params_flow.rb:7:10:7:15 | call to params | ActionController::Metal#params |
228+
| action_controller/params_flow.rb:11:10:11:15 | call to params | ActionController::Metal#params |
229+
| action_controller/params_flow.rb:15:10:15:15 | call to params | ActionController::Metal#params |
230+
| action_controller/params_flow.rb:19:10:19:15 | call to params | ActionController::Metal#params |
231+
| action_controller/params_flow.rb:23:10:23:15 | call to params | ActionController::Metal#params |
232+
| action_controller/params_flow.rb:27:10:27:15 | call to params | ActionController::Metal#params |
233+
| action_controller/params_flow.rb:31:10:31:15 | call to params | ActionController::Metal#params |
234+
| action_controller/params_flow.rb:35:10:35:15 | call to params | ActionController::Metal#params |
235+
| action_controller/params_flow.rb:39:10:39:15 | call to params | ActionController::Metal#params |
236+
| action_controller/params_flow.rb:43:10:43:15 | call to params | ActionController::Metal#params |
237+
| action_controller/params_flow.rb:47:10:47:15 | call to params | ActionController::Metal#params |
238+
| action_controller/params_flow.rb:51:10:51:15 | call to params | ActionController::Metal#params |
239+
| action_controller/params_flow.rb:55:10:55:15 | call to params | ActionController::Metal#params |
240+
| action_controller/params_flow.rb:59:10:59:15 | call to params | ActionController::Metal#params |
241+
| action_controller/params_flow.rb:63:10:63:15 | call to params | ActionController::Metal#params |
242+
| action_controller/params_flow.rb:67:10:67:15 | call to params | ActionController::Metal#params |
243+
| action_controller/params_flow.rb:71:10:71:15 | call to params | ActionController::Metal#params |
244+
| action_controller/params_flow.rb:75:10:75:15 | call to params | ActionController::Metal#params |
245+
| action_controller/params_flow.rb:79:10:79:15 | call to params | ActionController::Metal#params |
246+
| action_controller/params_flow.rb:83:10:83:15 | call to params | ActionController::Metal#params |
247+
| action_controller/params_flow.rb:87:10:87:15 | call to params | ActionController::Metal#params |
248+
| action_controller/params_flow.rb:91:10:91:15 | call to params | ActionController::Metal#params |
249+
| action_controller/params_flow.rb:95:10:95:15 | call to params | ActionController::Metal#params |
250+
| action_controller/params_flow.rb:99:10:99:15 | call to params | ActionController::Metal#params |
251+
| action_controller/params_flow.rb:103:10:103:15 | call to params | ActionController::Metal#params |
252+
| action_controller/params_flow.rb:107:10:107:15 | call to params | ActionController::Metal#params |
253+
| action_controller/params_flow.rb:111:10:111:15 | call to params | ActionController::Metal#params |
254+
| action_controller/params_flow.rb:112:23:112:28 | call to params | ActionController::Metal#params |
255+
| action_controller/params_flow.rb:116:10:116:15 | call to params | ActionController::Metal#params |
256+
| action_controller/params_flow.rb:117:31:117:36 | call to params | ActionController::Metal#params |
257+
| action_controller/params_flow.rb:121:10:121:15 | call to params | ActionController::Metal#params |
258+
| action_controller/params_flow.rb:122:31:122:36 | call to params | ActionController::Metal#params |
259+
| action_controller/params_flow.rb:126:10:126:15 | call to params | ActionController::Metal#params |
260+
| action_controller/params_flow.rb:127:24:127:29 | call to params | ActionController::Metal#params |
261+
| action_controller/params_flow.rb:130:14:130:19 | call to params | ActionController::Metal#params |
262+
| action_controller/params_flow.rb:135:10:135:15 | call to params | ActionController::Metal#params |
263+
| action_controller/params_flow.rb:136:32:136:37 | call to params | ActionController::Metal#params |
264+
| action_controller/params_flow.rb:139:22:139:27 | call to params | ActionController::Metal#params |
265+
| action_controller/params_flow.rb:144:10:144:15 | call to params | ActionController::Metal#params |
266+
| action_controller/params_flow.rb:145:32:145:37 | call to params | ActionController::Metal#params |
267+
| action_controller/params_flow.rb:148:22:148:27 | call to params | ActionController::Metal#params |
268+
| active_record/ActiveRecord.rb:28:30:28:35 | call to params | ActionController::Metal#params |
269+
| active_record/ActiveRecord.rb:29:29:29:34 | call to params | ActionController::Metal#params |
270+
| active_record/ActiveRecord.rb:30:31:30:36 | call to params | ActionController::Metal#params |
271+
| active_record/ActiveRecord.rb:32:21:32:26 | call to params | ActionController::Metal#params |
272+
| active_record/ActiveRecord.rb:34:34:34:39 | call to params | ActionController::Metal#params |
273+
| active_record/ActiveRecord.rb:35:23:35:28 | call to params | ActionController::Metal#params |
274+
| active_record/ActiveRecord.rb:35:38:35:43 | call to params | ActionController::Metal#params |
275+
| active_record/ActiveRecord.rb:43:10:43:15 | call to params | ActionController::Metal#params |
276+
| active_record/ActiveRecord.rb:50:11:50:16 | call to params | ActionController::Metal#params |
277+
| active_record/ActiveRecord.rb:54:12:54:17 | call to params | ActionController::Metal#params |
278+
| active_record/ActiveRecord.rb:59:12:59:17 | call to params | ActionController::Metal#params |
279+
| active_record/ActiveRecord.rb:62:15:62:20 | call to params | ActionController::Metal#params |
280+
| active_record/ActiveRecord.rb:68:21:68:26 | call to params | ActionController::Metal#params |
281+
| active_record/ActiveRecord.rb:72:18:72:23 | call to params | ActionController::Metal#params |
282+
| active_record/ActiveRecord.rb:76:24:76:29 | call to params | ActionController::Metal#params |
283+
| active_record/ActiveRecord.rb:76:49:76:54 | call to params | ActionController::Metal#params |
284+
| active_record/ActiveRecord.rb:80:25:80:30 | call to params | ActionController::Metal#params |
285+
| active_record/ActiveRecord.rb:80:50:80:55 | call to params | ActionController::Metal#params |
286+
| active_record/ActiveRecord.rb:88:21:88:26 | call to params | ActionController::Metal#params |
287+
| active_record/ActiveRecord.rb:92:27:92:32 | call to params | ActionController::Metal#params |
288+
| active_record/ActiveRecord.rb:92:52:92:57 | call to params | ActionController::Metal#params |
289+
| active_record/ActiveRecord.rb:96:28:96:33 | call to params | ActionController::Metal#params |
290+
| active_record/ActiveRecord.rb:96:53:96:58 | call to params | ActionController::Metal#params |
291+
| active_record/ActiveRecord.rb:106:59:106:64 | call to params | ActionController::Metal#params |
292+
| active_storage/active_storage.rb:41:21:41:26 | call to params | ActionController::Metal#params |
293+
| active_storage/active_storage.rb:42:24:42:29 | call to params | ActionController::Metal#params |
294+
| app/controllers/comments_controller.rb:3:5:3:18 | call to params | ActionDispatch::Request#params |
295+
| app/controllers/comments_controller.rb:4:5:4:22 | call to parameters | ActionDispatch::Request#parameters |
296+
| app/controllers/comments_controller.rb:5:5:5:15 | call to GET | ActionDispatch::Request#GET |
297+
| app/controllers/comments_controller.rb:6:5:6:16 | call to POST | ActionDispatch::Request#POST |
298+
| app/controllers/comments_controller.rb:7:5:7:28 | call to query_parameters | ActionDispatch::Request#query_parameters |
299+
| app/controllers/comments_controller.rb:8:5:8:30 | call to request_parameters | ActionDispatch::Request#request_parameters |
300+
| app/controllers/comments_controller.rb:9:5:9:31 | call to filtered_parameters | ActionDispatch::Request#filtered_parameters |
301+
| app/controllers/foo/bars_controller.rb:10:27:10:33 | call to cookies | ActionController::Metal#cookies |
302+
| app/controllers/foo/bars_controller.rb:13:21:13:26 | call to params | ActionController::Metal#params |
303+
| app/controllers/foo/bars_controller.rb:14:10:14:15 | call to params | ActionController::Metal#params |
304+
| app/controllers/foo/bars_controller.rb:21:21:21:26 | call to params | ActionController::Metal#params |
305+
| app/controllers/foo/bars_controller.rb:22:10:22:15 | call to params | ActionController::Metal#params |
306+
| app/graphql/mutations/dummy.rb:5:24:5:25 | id | GraphQL RoutedParameter |
307+
| app/graphql/mutations/dummy.rb:9:17:9:25 | something | GraphQL RoutedParameter |
308+
| app/graphql/resolvers/dummy_resolver.rb:6:24:6:25 | id | GraphQL RoutedParameter |
309+
| app/graphql/resolvers/dummy_resolver.rb:10:17:10:25 | something | GraphQL RoutedParameter |
310+
| app/graphql/types/query_type.rb:10:18:10:23 | number | GraphQL RoutedParameter |
311+
| app/graphql/types/query_type.rb:18:23:18:33 | blah_number | GraphQL RoutedParameter |
312+
| app/graphql/types/query_type.rb:27:20:27:25 | **args | GraphQL RoutedParameter |
313+
| app/graphql/types/query_type.rb:36:34:36:37 | arg1 | GraphQL RoutedParameter |
314+
| app/graphql/types/query_type.rb:36:41:36:46 | **rest | GraphQL RoutedParameter |
315+
| app/views/foo/bars/show.html.erb:5:9:5:14 | call to params | ActionController::Metal#params |
225316
cookiesCalls
226317
| app/controllers/foo/bars_controller.rb:10:27:10:33 | call to cookies |
227318
cookiesSources

ruby/ql/test/library-tests/frameworks/ActionController.ql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
private import codeql.ruby.AST
22
private import codeql.ruby.frameworks.ActionController
33
private import codeql.ruby.frameworks.Rails
4+
private import codeql.ruby.frameworks.ActionView
5+
private import codeql.ruby.Concepts
46

57
query predicate actionControllerControllerClasses(ActionControllerControllerClass cls) { any() }
68

@@ -10,6 +12,10 @@ query predicate paramsCalls(Rails::ParamsCall c) { any() }
1012

1113
query predicate paramsSources(ParamsSource src) { any() }
1214

15+
query predicate httpInputAccesses(Http::Server::RequestInputAccess a, string sourceType) {
16+
sourceType = a.getSourceType()
17+
}
18+
1319
query predicate cookiesCalls(Rails::CookiesCall c) { any() }
1420

1521
query predicate cookiesSources(CookiesSource src) { any() }

ruby/ql/test/library-tests/frameworks/ActionDispatch.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ actionDispatchRoutes
3636
actionDispatchControllerMethods
3737
| app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:2:3:3:5 | index |
3838
| app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:5:3:6:5 | show |
39-
| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:2:3:3:5 | index |
40-
| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:5:3:6:5 | show |
39+
| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:2:3:10:5 | index |
40+
| app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:12:3:13:5 | show |
4141
| app/config/routes.rb:7:5:7:37 | call to post | app/controllers/posts_controller.rb:8:3:9:5 | upvote |
4242
| app/config/routes.rb:27:3:27:48 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show |
4343
| app/config/routes.rb:28:3:28:50 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show |
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
class CommentsController < ApplicationController
22
def index
3+
request.params
4+
request.parameters
5+
request.GET
6+
request.POST
7+
request.query_parameters
8+
request.request_parameters
9+
request.filtered_parameters
310
end
411

512
def show
613
end
7-
end
14+
end

0 commit comments

Comments
 (0)