generated from githubuniverseworkshops/template-workshop
-
Notifications
You must be signed in to change notification settings - Fork 29
/
solution.ql
53 lines (47 loc) · 1.73 KB
/
solution.ql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* @name URL redirection
* @kind path-problem
* @id rb/workshop/url-redirection
*/
import ruby
import codeql.ruby.frameworks.ActionController
import codeql.ruby.Concepts
import codeql.ruby.dataflow.RemoteFlowSources
import codeql.ruby.TaintTracking
import DataFlow::PathGraph
/**
* Holds if `redirectLocation` is the target of a URL redirect call
* within a Rails application and `method` is the HTTP request handler
* method enclosing the call.
*/
predicate isRedirect(DataFlow::Node redirectLocation, GetHandlerMethod method) {
exists(Http::Server::HttpRedirectResponse redirectCall |
redirectCall.getRedirectLocation() = redirectLocation and
redirectCall.asExpr().getExpr().getEnclosingMethod() = method
)
}
/**
* A method in a Rails `ActionController` subclass that is likely
* to be the target of a route handler for an HTTP `GET` request.
*/
class GetHandlerMethod extends Ast::MethodBase {
GetHandlerMethod() {
this.(ActionControllerActionMethod).getARoute().getHttpMethod() = "get"
or
not exists(this.(ActionControllerActionMethod).getARoute()) and
exists(ActionControllerControllerClass c | this = c.getAMethod()) and
not this.getName().regexpMatch(".*(create|update|destroy|delete).*")
}
}
class UrlRedirectionConfig extends TaintTracking::Configuration {
UrlRedirectionConfig() { this = "UrlRedirectionConfig" }
override predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource
}
override predicate isSink(DataFlow::Node sink) {
isRedirect(sink, _)
}
}
from UrlRedirectionConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink, source, sink, "Potential URL redirection from $@", source, "this source"