Ruby: Fix rack response tracking

Use type tracking instead of getReturningNode, which seems to be faster
and works correctly for the cases I've tried.
This commit is contained in:
Harry Maclean
2023-01-23 21:43:04 +00:00
parent 21ce9b448a
commit c1207e0938
3 changed files with 33 additions and 1 deletions

View File

@@ -9,6 +9,8 @@ private import codeql.ruby.DataFlow
* Provides modeling for the Rack library.
*/
module Rack {
import codeql.ruby.typetracking.TypeTracker
/**
* A class that may be a rack application.
* This is a class that has a `call` method that takes a single argument
@@ -20,7 +22,7 @@ module Rack {
AppCandidate() {
call = this.getInstanceMethod("call") and
call.getNumberOfParameters() = 1 and
exists(DataFlow::LocalSourceNode resp | isRackResponse(resp) | resp.flowsTo(call.getReturn()))
call.getReturn() = trackRackResponse()
}
/**
@@ -37,4 +39,15 @@ module Rack {
exists(DataFlow::LocalSourceNode n | n.asExpr() = arr | n.flowsTo(r))
)
}
private DataFlow::LocalSourceNode trackRackResponse(TypeTracker t) {
t.start() and
isRackResponse(result)
or
exists(TypeTracker t2 | result = trackRackResponse(t2).track(t2, t))
}
private DataFlow::Node trackRackResponse() {
trackRackResponse(TypeTracker::end()).flowsTo(result)
}
}

View File

@@ -1,3 +1,4 @@
| rack.rb:1:1:5:3 | HelloWorld | rack.rb:2:12:2:14 | env |
| rack.rb:7:1:16:3 | Proxy | rack.rb:12:12:12:18 | the_env |
| rack.rb:18:1:31:3 | Logger | rack.rb:24:12:24:14 | env |
| rack.rb:45:1:61:3 | Baz | rack.rb:46:12:46:14 | env |

View File

@@ -41,3 +41,21 @@ class Bar
nil
end
end
class Baz
def call(env)
run(env)
end
def run(env)
if env[:foo] == "foo"
[200, {}, "foo"]
else
error
end
end
def error
[400, {}, "nope"]
end
end