Skip to content

Commit 0a7ae58

Browse files
committed
Ruby: revert to simpler Rack PotentialResponseNode def and use TypeBackTracker to track instances
1 parent a5d8db6 commit 0a7ae58

File tree

2 files changed

+14
-12
lines changed

2 files changed

+14
-12
lines changed

ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@ private import codeql.ruby.DataFlow
77
private import codeql.ruby.typetracking.TypeTracker
88
private import Response::Private as RP
99

10-
private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t, RP::PotentialResponseNode n) {
10+
/** A method node for a method named `call`. */
11+
private class CallMethodNode extends DataFlow::MethodNode {
12+
CallMethodNode() { this.getMethodName() = "call" }
13+
}
14+
15+
private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, CallMethodNode call) {
1116
t.start() and
12-
result = n
17+
result = call.getAReturningNode()
1318
or
14-
exists(TypeTracker t2 | result = trackRackResponse(t2, n).track(t2, t))
19+
exists(TypeBackTracker t2 | result = trackRackResponse(t2, call).backtrack(t2, t))
1520
}
1621

17-
private DataFlow::Node trackRackResponse(RP::PotentialResponseNode n) {
18-
trackRackResponse(TypeTracker::end(), n).flowsTo(result)
22+
private RP::PotentialResponseNode trackRackResponse(CallMethodNode call) {
23+
result = trackRackResponse(TypeBackTracker::end(), call)
1924
}
2025

2126
/**
@@ -28,21 +33,21 @@ module App {
2833
* (traditionally called `env`) and returns a rack-compatible response.
2934
*/
3035
class AppCandidate extends DataFlow::ClassNode {
31-
private DataFlow::MethodNode call;
36+
private CallMethodNode call;
3237
private RP::PotentialResponseNode resp;
3338

3439
AppCandidate() {
3540
call = this.getInstanceMethod("call") and
3641
call.getNumberOfParameters() = 1 and
37-
call.getAReturningNode() = trackRackResponse(resp)
42+
resp = trackRackResponse(call)
3843
}
3944

4045
/**
4146
* Gets the environment of the request, which is the lone parameter to the `call` method.
4247
*/
4348
DataFlow::ParameterNode getEnv() { result = call.getParameter(0) }
4449

45-
/** Gets the response returned from the request. */
50+
/** Gets the response returned from a request to this application. */
4651
RP::PotentialResponseNode getResponse() { result = resp }
4752
}
4853
}

ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@ module Private {
2424
/** A `DataFlow::Node` that may be a rack response. This is detected heuristically, if something "looks like" a rack response syntactically then we consider it to be a potential response node. */
2525
class PotentialResponseNode extends DataFlow::ArrayLiteralNode {
2626
// [status, headers, body]
27-
PotentialResponseNode() {
28-
this.getNumberOfArguments() = 3 and
29-
this.asExpr().getExpr().getEnclosingModule+().getAMethod().getName() = "call"
30-
}
27+
PotentialResponseNode() { this.getNumberOfArguments() = 3 }
3128

3229
/**
3330
* Gets an HTTP status code that may be returned in this response.

0 commit comments

Comments
 (0)