Skip to content

Commit c87c266

Browse files
committed
ruby: add Rack::ResponseNode#getAStatusCode
1 parent e7e0cf5 commit c87c266

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,25 @@ module Rack {
3030
DataFlow::ParameterNode getEnv() { result = call.getParameter(0) }
3131
}
3232

33+
private DataFlow::LocalSourceNode trackStatusCode(TypeTracker t, int i) {
34+
t.start() and
35+
result.getConstantValue().isInt(i)
36+
or
37+
exists(TypeTracker t2 | result = trackStatusCode(t2, i).track(t2, t))
38+
}
39+
40+
private DataFlow::Node trackStatusCode(int i) {
41+
trackStatusCode(TypeTracker::end(), i).flowsTo(result)
42+
}
43+
3344
class ResponseNode extends DataFlow::ArrayLiteralNode {
3445
// [status, headers, body]
3546
ResponseNode() { this.getNumberOfArguments() = 3 }
47+
48+
/**
49+
* Gets an HTTP status code that may be returned in this response.
50+
*/
51+
int getAStatusCode() { this.getElement(0) = trackStatusCode(result) }
3652
}
3753

3854
private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t) {
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
| rack.rb:1:1:5:3 | HelloWorld | rack.rb:2:12:2:14 | env |
2-
| rack.rb:7:1:16:3 | Proxy | rack.rb:12:12:12:18 | the_env |
3-
| rack.rb:18:1:31:3 | Logger | rack.rb:24:12:24:14 | env |
4-
| rack.rb:45:1:61:3 | Baz | rack.rb:46:12:46:14 | env |
1+
rackApps
2+
| rack.rb:1:1:9:3 | HelloWorld | rack.rb:2:12:2:14 | env |
3+
| rack.rb:11:1:20:3 | Proxy | rack.rb:16:12:16:18 | the_env |
4+
| rack.rb:22:1:35:3 | Logger | rack.rb:28:12:28:14 | env |
5+
| rack.rb:49:1:65:3 | Baz | rack.rb:50:12:50:14 | env |
6+
rackResponseStatusCodes
7+
| rack.rb:7:5:7:63 | call to [] | 200 |
8+
| rack.rb:7:5:7:63 | call to [] | 500 |
9+
| rack.rb:39:5:39:13 | call to [] | 1 |
10+
| rack.rb:56:7:56:22 | call to [] | 200 |
11+
| rack.rb:63:5:63:21 | call to [] | 400 |

ruby/ql/test/library-tests/frameworks/rack/Rack.ql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@ private import codeql.ruby.frameworks.Rack
22
private import codeql.ruby.DataFlow
33

44
query predicate rackApps(Rack::AppCandidate c, DataFlow::ParameterNode env) { env = c.getEnv() }
5+
6+
query predicate rackResponseStatusCodes(Rack::ResponseNode resp, int status) {
7+
status = resp.getAStatusCode()
8+
}

ruby/ql/test/library-tests/frameworks/rack/rack.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
class HelloWorld
22
def call(env)
3-
[200, {'Content-Type' => 'text/plain'}, ['Hello World']]
3+
status = 200
4+
if something_goes_wrong(env)
5+
status = 500
6+
end
7+
[status, {'Content-Type' => 'text/plain'}, ['Hello World']]
48
end
59
end
610

0 commit comments

Comments
 (0)