Skip to content

Commit 7c2b19b

Browse files
authored
tweaks and add Zip::File.open_buffer to query
1 parent 01cb408 commit 7c2b19b

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

ruby/ql/src/experimental/decompression-api/DecompressionApi.ql

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,18 @@ import codeql.ruby.TaintTracking
1818
import DataFlow::PathGraph
1919

2020
class DecompressionApiUse extends DataFlow::Node {
21+
private DataFlow::CallNode call;
22+
2123
// this should find the first argument of Zlib::Inflate.inflate
2224
DecompressionApiUse() {
23-
this =
24-
API::getTopLevelMember("Zlib").getMember("Inflate").getAMethodCall("inflate").getArgument(0)
25+
this = call.getArgument(0) and
26+
(
27+
call = API::getTopLevelMember("Zlib").getMember("Inflate").getAMethodCall("inflate") or
28+
call = API::getTopLevelMember("Zip").getMember("File").getAMethodCall("open_buffer")
29+
)
2530
}
31+
32+
DataFlow::CallNode getCall() { result = call }
2633
}
2734

2835
class Configuration extends TaintTracking::Configuration {
@@ -32,12 +39,14 @@ class Configuration extends TaintTracking::Configuration {
3239
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
3340

3441
// our Decompression APIs defined above will the the sinks we use for this query
35-
override predicate isSink(DataFlow::Node sink) { sink instanceof DecompressionApiUse }
42+
override predicate isSink(DataFlow::Node sink) {
43+
sink.(DataFlow::CallNode) instanceof DecompressionApiUse
44+
}
3645
}
3746

3847
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
3948
where config.hasFlowPath(source, sink)
40-
select sink.getNode(), source, sink,
49+
select sink.getNode().(DecompressionApiUse), source, sink,
4150
"This call to $@ is unsafe because user-controlled data is used to set the object being decompressed, which could lead to a denial of service attack or malicious code extracted from an unknown source.",
42-
sink.getNode().asExpr().getExpr().getParent(),
43-
sink.getNode().asExpr().getExpr().getParent().toString()
51+
sink.getNode().(DecompressionApiUse).getCall(),
52+
sink.getNode().(DecompressionApiUse).getCall().getMethodName()
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
edges
2-
| decompression_api.rb:3:31:3:36 | call to params : | decompression_api.rb:3:31:3:43 | ...[...] |
3-
| decompression_api.rb:13:44:13:49 | call to params : | decompression_api.rb:13:44:13:56 | ...[...] |
2+
| decompression_api.rb:4:31:4:36 | call to params : | decompression_api.rb:4:31:4:43 | ...[...] |
3+
| decompression_api.rb:14:31:14:36 | call to params : | decompression_api.rb:14:31:14:43 | ...[...] |
44
nodes
5-
| decompression_api.rb:3:31:3:36 | call to params : | semmle.label | call to params : |
6-
| decompression_api.rb:3:31:3:43 | ...[...] | semmle.label | ...[...] |
7-
| decompression_api.rb:13:44:13:49 | call to params : | semmle.label | call to params : |
8-
| decompression_api.rb:13:44:13:56 | ...[...] | semmle.label | ...[...] |
5+
| decompression_api.rb:4:31:4:36 | call to params : | semmle.label | call to params : |
6+
| decompression_api.rb:4:31:4:43 | ...[...] | semmle.label | ...[...] |
7+
| decompression_api.rb:14:31:14:36 | call to params : | semmle.label | call to params : |
8+
| decompression_api.rb:14:31:14:43 | ...[...] | semmle.label | ...[...] |
99
subpaths
1010
#select
11-
| decompression_api.rb:3:31:3:43 | ...[...] | decompression_api.rb:3:31:3:36 | call to params : | decompression_api.rb:3:31:3:43 | ...[...] | This call to $@ is unsafe because user-controlled data is used to set the object being decompressed, which could lead to a denial of service attack or malicious code extracted from an unknown source. | decompression_api.rb:3:9:3:44 | call to inflate | call to inflate |
12-
| decompression_api.rb:13:44:13:56 | ...[...] | decompression_api.rb:13:44:13:49 | call to params : | decompression_api.rb:13:44:13:56 | ...[...] | This call to $@ is unsafe because user-controlled data is used to set the object being decompressed, which could lead to a denial of service attack or malicious code extracted from an unknown source. | decompression_api.rb:13:9:13:57 | call to inflate | call to inflate |
11+
| decompression_api.rb:4:31:4:43 | ...[...] | decompression_api.rb:4:31:4:36 | call to params : | decompression_api.rb:4:31:4:43 | ...[...] | This call to $@ is unsafe because user-controlled data is used to set the object being decompressed, which could lead to a denial of service attack or malicious code extracted from an unknown source. | decompression_api.rb:4:9:4:44 | call to inflate | inflate |
12+
| decompression_api.rb:14:31:14:43 | ...[...] | decompression_api.rb:14:31:14:36 | call to params : | decompression_api.rb:14:31:14:43 | ...[...] | This call to $@ is unsafe because user-controlled data is used to set the object being decompressed, which could lead to a denial of service attack or malicious code extracted from an unknown source. | decompression_api.rb:14:9:14:44 | call to open_buffer | open_buffer |
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
class TestController < ActionController::Base
2+
# this should get picked up
23
def unsafe_zlib_unzip
34
Zlib::Inflate.inflate(params[:file])
45
end
56

7+
# this should not get picked up
68
def safe_zlib_unzip
79
Zlib::Inflate.inflate(file)
810
end
911

12+
# this should get picked up
13+
def unsafe_zlib_unzip
14+
Zip::File.open_buffer(params[:file])
15+
end
1016

11-
DECOMPRESSION_LIB = Zlib
12-
def unsafe_zlib_unzip_const
13-
DECOMPRESSION_LIB::Inflate.inflate(params[:file])
17+
# this should not get picked up
18+
def safe_zlib_unzip
19+
Zip::File.open_buffer(file)
1420
end
1521
end

0 commit comments

Comments
 (0)