Skip to content

Commit fac1738

Browse files
committed
Ruby: Add RequestInputAccess concept
This sits in between RemoteFlowSource and specific classes like ParamsSource from ActionController. It represents any user-controller input from an incoming HTTP request. This more closely aligns our concepts with the JS library, and allows us to specifically target sources from HTTP requests in the HttpToFileAccess query.
1 parent ff1d96c commit fac1738

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

ruby/ql/lib/codeql/ruby/Concepts.qll

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,34 @@ module HTTP {
290290
}
291291
}
292292

293+
/**
294+
* An access to a user-controlled HTTP request input. For example, the URL or body of a request.
295+
* Instances of this class automatically become `RemoteFlowSource`s.
296+
*
297+
* Extend this class to refine existing API models. If you want to model new APIs,
298+
* extend `RequestInputAccess::Range` instead.
299+
*/
300+
class RequestInputAccess extends DataFlow::Node instanceof RequestInputAccess::Range {
301+
string getSourceType() { result = super.getSourceType() }
302+
}
303+
304+
/** Provides a class for modeling new HTTP request inputs. */
305+
module RequestInputAccess {
306+
/**
307+
* An access to a user-controlled HTTP request input.
308+
*
309+
* Extend this class to model new APIs. If you want to refine existing API models,
310+
* extend `RequestInputAccess` instead.
311+
*/
312+
abstract class Range extends DataFlow::Node {
313+
abstract string getSourceType();
314+
}
315+
}
316+
317+
private class RequestInputAccessAsRemoteFlowSource extends RemoteFlowSource::Range instanceof RequestInputAccess {
318+
override string getSourceType() { result = this.(RequestInputAccess).getSourceType() }
319+
}
320+
293321
/**
294322
* A function that will handle incoming HTTP requests.
295323
*
@@ -343,7 +371,7 @@ module HTTP {
343371
}
344372

345373
/** A parameter that will receive parts of the url when handling an incoming request. */
346-
private class RoutedParameter extends RemoteFlowSource::Range, DataFlow::ParameterNode {
374+
private class RoutedParameter extends RequestInputAccess::Range, DataFlow::ParameterNode {
347375
RequestHandler handler;
348376

349377
RoutedParameter() { this.getParameter() = handler.getARoutedParameter() }

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ private import codeql.ruby.ast.internal.Module
1111
private import codeql.ruby.ApiGraphs
1212
private import ActionView
1313
private import codeql.ruby.frameworks.ActionDispatch
14+
private import codeql.ruby.Concepts
1415

1516
/**
1617
* A `ClassDeclaration` for a class that extends `ActionController::Base`.
@@ -126,7 +127,7 @@ abstract class ParamsCall extends MethodCall {
126127
* A `RemoteFlowSource::Range` to represent accessing the
127128
* ActionController parameters available via the `params` method.
128129
*/
129-
class ParamsSource extends RemoteFlowSource::Range {
130+
class ParamsSource extends HTTP::Server::RequestInputAccess::Range {
130131
ParamsSource() { this.asExpr().getExpr() instanceof ParamsCall }
131132

132133
override string getSourceType() { result = "ActionController::Metal#params" }
@@ -143,7 +144,7 @@ abstract class CookiesCall extends MethodCall {
143144
* A `RemoteFlowSource::Range` to represent accessing the
144145
* ActionController parameters available via the `cookies` method.
145146
*/
146-
class CookiesSource extends RemoteFlowSource::Range {
147+
class CookiesSource extends HTTP::Server::RequestInputAccess::Range {
147148
CookiesSource() { this.asExpr().getExpr() instanceof CookiesCall }
148149

149150
override string getSourceType() { result = "ActionController::Metal#cookies" }

0 commit comments

Comments
 (0)