Skip to content

Commit 9da94fb

Browse files
committed
Fix #19294, Ruby NetHttpRequest improvements
1 parent 05572b4 commit 9da94fb

File tree

2 files changed

+26
-4
lines changed
  • ruby/ql

2 files changed

+26
-4
lines changed

ruby/ql/lib/codeql/ruby/frameworks/http_clients/NetHttp.qll

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,22 @@ private import codeql.ruby.DataFlow
1212
/**
1313
* A `Net::HTTP` call which initiates an HTTP request.
1414
* ```ruby
15+
* # one-off request
1516
* Net::HTTP.get("http://example.com/")
1617
* Net::HTTP.post("http://example.com/", "some_data")
1718
* req = Net::HTTP.new("example.com")
1819
* response = req.get("/")
20+
*
21+
* # connection re-use
22+
* Net::HTTP.start("http://example.com") do |http|
23+
* http.get("/")
24+
* end
1925
* ```
2026
*/
2127
class NetHttpRequest extends Http::Client::Request::Range instanceof DataFlow::CallNode {
2228
private DataFlow::CallNode request;
23-
private API::Node requestNode;
29+
API::Node requestNode;
30+
API::Node connectionNode;
2431
private boolean returnsResponseBody;
2532

2633
NetHttpRequest() {
@@ -30,20 +37,27 @@ class NetHttpRequest extends Http::Client::Request::Range instanceof DataFlow::C
3037
|
3138
// Net::HTTP.get(...)
3239
method in ["get", "get_response"] and
33-
requestNode = API::getTopLevelMember("Net").getMember("HTTP").getReturn(method) and
40+
connectionNode = API::getTopLevelMember("Net").getMember("HTTP") and
41+
requestNode = connectionNode.getReturn(method) and
3442
returnsResponseBody = true
3543
or
3644
// Net::HTTP.post(...).body
3745
method in ["post", "post_form"] and
38-
requestNode = API::getTopLevelMember("Net").getMember("HTTP").getReturn(method) and
46+
connectionNode = API::getTopLevelMember("Net").getMember("HTTP") and
47+
requestNode = connectionNode.getReturn(method) and
3948
returnsResponseBody = false
4049
or
4150
// Net::HTTP.new(..).get(..).body
51+
// Net::HTTP.start(..) do |http| http.get(..) end
4252
method in [
4353
"get", "get2", "request_get", "head", "head2", "request_head", "delete", "put", "patch",
4454
"post", "post2", "request_post", "request"
4555
] and
46-
requestNode = API::getTopLevelMember("Net").getMember("HTTP").getInstance().getReturn(method) and
56+
connectionNode = [
57+
API::getTopLevelMember("Net").getMember("HTTP").getInstance(),
58+
API::getTopLevelMember("Net").getMember("HTTP").getMethod("start").getBlock().getParameter(0)
59+
] and
60+
requestNode = connectionNode.getReturn(method) and
4761
returnsResponseBody = false
4862
)
4963
}

ruby/ql/test/library-tests/frameworks/http_clients/NetHttp.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ def get(domain, path)
2727
get("example.com", "/").body
2828

2929
Net::HTTP.post(uri, "some_body") # note: response body not accessed
30+
31+
http = Net::HTTP.new("https://example.com")
32+
root_get = Net::HTTP::Get.new("/")
33+
http.request(root_get)
34+
35+
Net::HTTP.start("https://example.com") do |http|
36+
http.get("/")
37+
end

0 commit comments

Comments
 (0)