Skip to content

Commit 5b5ca05

Browse files
committed
Ruby: Post-processing query for inline test expectations
1 parent e2b614d commit 5b5ca05

File tree

5 files changed

+76
-54
lines changed

5 files changed

+76
-54
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @kind test-postprocess
3+
*/
4+
5+
private import ruby
6+
private import codeql.util.test.InlineExpectationsTest as T
7+
private import internal.InlineExpectationsTestImpl
8+
import T::TestPostProcessing
9+
import T::TestPostProcessing::Make<Impl, Input>
10+
11+
private module Input implements T::TestPostProcessing::InputSig<Impl> {
12+
string getRelativeUrl(Location location) {
13+
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
14+
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
15+
f = location.getFile()
16+
|
17+
result =
18+
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
19+
)
20+
}
21+
}

ruby/ql/test/query-tests/security/cwe-022/ArchiveApiPathTraversal.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ class TestContoller < ActionController::Base
22

33
# this is vulnerable
44
def upload
5-
untar params[:file], params[:filename]
5+
untar params[:file], params[:filename] # $ Source=upload
66
end
77

88
# this is vulnerable
99
def unpload_zip
10-
unzip params[:file]
10+
unzip params[:file] # $ Source=upload_zip
1111
end
1212

1313
# this is vulnerable
1414
def create_new_zip
15-
zip params[:filename], files
15+
zip params[:filename], files # $ Source=create_new_zip
1616
end
1717

1818
# these are not vulnerable because of the string compare sanitizer
@@ -56,7 +56,7 @@ def untar(io, destination)
5656
else
5757
destination_directory = File.dirname(destination_file)
5858
FileUtils.mkdir_p destination_directory unless File.directory?(destination_directory)
59-
File.open destination_file, "wb" do |f|
59+
File.open destination_file, "wb" do |f| # $ Alert=upload
6060
f.print tarfile.read
6161
end
6262
end
@@ -65,15 +65,15 @@ def untar(io, destination)
6565
end
6666

6767
def unzip(file)
68-
Zip::File.open(file) do |zip_file|
68+
Zip::File.open(file) do |zip_file| # $ Alert=upload_zip
6969
zip_file.each do |entry|
7070
entry.extract
7171
end
7272
end
7373
end
7474

7575
def zip(filename, files = [])
76-
Zip::File.new(filename) do |zf|
76+
Zip::File.new(filename) do |zf| # $ Alert=create_new_zip
7777
files.each do |f|
7878
zf.add f
7979
end

ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
#select
2+
| ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | This path depends on a $@. | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | user-provided value |
3+
| ArchiveApiPathTraversal.rb:68:20:68:23 | file | ArchiveApiPathTraversal.rb:10:11:10:16 | call to params | ArchiveApiPathTraversal.rb:68:20:68:23 | file | This path depends on a $@. | ArchiveApiPathTraversal.rb:10:11:10:16 | call to params | user-provided value |
4+
| ArchiveApiPathTraversal.rb:76:19:76:26 | filename | ArchiveApiPathTraversal.rb:15:9:15:14 | call to params | ArchiveApiPathTraversal.rb:76:19:76:26 | filename | This path depends on a $@. | ArchiveApiPathTraversal.rb:15:9:15:14 | call to params | user-provided value |
5+
| tainted_path.rb:5:26:5:29 | path | tainted_path.rb:4:12:4:17 | call to params | tainted_path.rb:5:26:5:29 | path | This path depends on a $@. | tainted_path.rb:4:12:4:17 | call to params | user-provided value |
6+
| tainted_path.rb:11:26:11:29 | path | tainted_path.rb:10:31:10:36 | call to params | tainted_path.rb:11:26:11:29 | path | This path depends on a $@. | tainted_path.rb:10:31:10:36 | call to params | user-provided value |
7+
| tainted_path.rb:17:26:17:29 | path | tainted_path.rb:16:28:16:33 | call to params | tainted_path.rb:17:26:17:29 | path | This path depends on a $@. | tainted_path.rb:16:28:16:33 | call to params | user-provided value |
8+
| tainted_path.rb:23:26:23:29 | path | tainted_path.rb:22:29:22:34 | call to params | tainted_path.rb:23:26:23:29 | path | This path depends on a $@. | tainted_path.rb:22:29:22:34 | call to params | user-provided value |
9+
| tainted_path.rb:29:26:29:29 | path | tainted_path.rb:28:22:28:27 | call to params | tainted_path.rb:29:26:29:29 | path | This path depends on a $@. | tainted_path.rb:28:22:28:27 | call to params | user-provided value |
10+
| tainted_path.rb:35:26:35:29 | path | tainted_path.rb:34:29:34:34 | call to params | tainted_path.rb:35:26:35:29 | path | This path depends on a $@. | tainted_path.rb:34:29:34:34 | call to params | user-provided value |
11+
| tainted_path.rb:41:26:41:29 | path | tainted_path.rb:40:26:40:31 | call to params | tainted_path.rb:41:26:41:29 | path | This path depends on a $@. | tainted_path.rb:40:26:40:31 | call to params | user-provided value |
12+
| tainted_path.rb:48:26:48:29 | path | tainted_path.rb:47:43:47:48 | call to params | tainted_path.rb:48:26:48:29 | path | This path depends on a $@. | tainted_path.rb:47:43:47:48 | call to params | user-provided value |
13+
| tainted_path.rb:60:26:60:29 | path | tainted_path.rb:59:40:59:45 | call to params | tainted_path.rb:60:26:60:29 | path | This path depends on a $@. | tainted_path.rb:59:40:59:45 | call to params | user-provided value |
14+
| tainted_path.rb:72:15:72:18 | path | tainted_path.rb:71:40:71:45 | call to params | tainted_path.rb:72:15:72:18 | path | This path depends on a $@. | tainted_path.rb:71:40:71:45 | call to params | user-provided value |
15+
| tainted_path.rb:78:19:78:22 | path | tainted_path.rb:77:40:77:45 | call to params | tainted_path.rb:78:19:78:22 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value |
16+
| tainted_path.rb:79:14:79:17 | path | tainted_path.rb:77:40:77:45 | call to params | tainted_path.rb:79:14:79:17 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value |
17+
| tainted_path.rb:85:10:85:13 | path | tainted_path.rb:84:40:84:45 | call to params | tainted_path.rb:85:10:85:13 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value |
18+
| tainted_path.rb:86:25:86:28 | path | tainted_path.rb:84:40:84:45 | call to params | tainted_path.rb:86:25:86:28 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value |
19+
| tainted_path.rb:92:11:92:14 | path | tainted_path.rb:90:40:90:45 | call to params | tainted_path.rb:92:11:92:14 | path | This path depends on a $@. | tainted_path.rb:90:40:90:45 | call to params | user-provided value |
120
edges
221
| ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | ArchiveApiPathTraversal.rb:5:26:5:42 | ...[...] | provenance | |
322
| ArchiveApiPathTraversal.rb:5:26:5:42 | ...[...] | ArchiveApiPathTraversal.rb:49:17:49:27 | destination | provenance | |
@@ -152,22 +171,3 @@ nodes
152171
| tainted_path.rb:90:40:90:52 | ...[...] | semmle.label | ...[...] |
153172
| tainted_path.rb:92:11:92:14 | path | semmle.label | path |
154173
subpaths
155-
#select
156-
| ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | This path depends on a $@. | ArchiveApiPathTraversal.rb:5:26:5:31 | call to params | user-provided value |
157-
| ArchiveApiPathTraversal.rb:68:20:68:23 | file | ArchiveApiPathTraversal.rb:10:11:10:16 | call to params | ArchiveApiPathTraversal.rb:68:20:68:23 | file | This path depends on a $@. | ArchiveApiPathTraversal.rb:10:11:10:16 | call to params | user-provided value |
158-
| ArchiveApiPathTraversal.rb:76:19:76:26 | filename | ArchiveApiPathTraversal.rb:15:9:15:14 | call to params | ArchiveApiPathTraversal.rb:76:19:76:26 | filename | This path depends on a $@. | ArchiveApiPathTraversal.rb:15:9:15:14 | call to params | user-provided value |
159-
| tainted_path.rb:5:26:5:29 | path | tainted_path.rb:4:12:4:17 | call to params | tainted_path.rb:5:26:5:29 | path | This path depends on a $@. | tainted_path.rb:4:12:4:17 | call to params | user-provided value |
160-
| tainted_path.rb:11:26:11:29 | path | tainted_path.rb:10:31:10:36 | call to params | tainted_path.rb:11:26:11:29 | path | This path depends on a $@. | tainted_path.rb:10:31:10:36 | call to params | user-provided value |
161-
| tainted_path.rb:17:26:17:29 | path | tainted_path.rb:16:28:16:33 | call to params | tainted_path.rb:17:26:17:29 | path | This path depends on a $@. | tainted_path.rb:16:28:16:33 | call to params | user-provided value |
162-
| tainted_path.rb:23:26:23:29 | path | tainted_path.rb:22:29:22:34 | call to params | tainted_path.rb:23:26:23:29 | path | This path depends on a $@. | tainted_path.rb:22:29:22:34 | call to params | user-provided value |
163-
| tainted_path.rb:29:26:29:29 | path | tainted_path.rb:28:22:28:27 | call to params | tainted_path.rb:29:26:29:29 | path | This path depends on a $@. | tainted_path.rb:28:22:28:27 | call to params | user-provided value |
164-
| tainted_path.rb:35:26:35:29 | path | tainted_path.rb:34:29:34:34 | call to params | tainted_path.rb:35:26:35:29 | path | This path depends on a $@. | tainted_path.rb:34:29:34:34 | call to params | user-provided value |
165-
| tainted_path.rb:41:26:41:29 | path | tainted_path.rb:40:26:40:31 | call to params | tainted_path.rb:41:26:41:29 | path | This path depends on a $@. | tainted_path.rb:40:26:40:31 | call to params | user-provided value |
166-
| tainted_path.rb:48:26:48:29 | path | tainted_path.rb:47:43:47:48 | call to params | tainted_path.rb:48:26:48:29 | path | This path depends on a $@. | tainted_path.rb:47:43:47:48 | call to params | user-provided value |
167-
| tainted_path.rb:60:26:60:29 | path | tainted_path.rb:59:40:59:45 | call to params | tainted_path.rb:60:26:60:29 | path | This path depends on a $@. | tainted_path.rb:59:40:59:45 | call to params | user-provided value |
168-
| tainted_path.rb:72:15:72:18 | path | tainted_path.rb:71:40:71:45 | call to params | tainted_path.rb:72:15:72:18 | path | This path depends on a $@. | tainted_path.rb:71:40:71:45 | call to params | user-provided value |
169-
| tainted_path.rb:78:19:78:22 | path | tainted_path.rb:77:40:77:45 | call to params | tainted_path.rb:78:19:78:22 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value |
170-
| tainted_path.rb:79:14:79:17 | path | tainted_path.rb:77:40:77:45 | call to params | tainted_path.rb:79:14:79:17 | path | This path depends on a $@. | tainted_path.rb:77:40:77:45 | call to params | user-provided value |
171-
| tainted_path.rb:85:10:85:13 | path | tainted_path.rb:84:40:84:45 | call to params | tainted_path.rb:85:10:85:13 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value |
172-
| tainted_path.rb:86:25:86:28 | path | tainted_path.rb:84:40:84:45 | call to params | tainted_path.rb:86:25:86:28 | path | This path depends on a $@. | tainted_path.rb:84:40:84:45 | call to params | user-provided value |
173-
| tainted_path.rb:92:11:92:14 | path | tainted_path.rb:90:40:90:45 | call to params | tainted_path.rb:92:11:92:14 | path | This path depends on a $@. | tainted_path.rb:90:40:90:45 | call to params | user-provided value |
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
queries/security/cwe-022/PathInjection.ql
1+
query: queries/security/cwe-022/PathInjection.ql
2+
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
11
class FooController < ActionController::Base
22
# BAD
33
def route0
4-
path = params[:path]
5-
@content = File.read path
4+
path = params[:path] # $ Source=path1
5+
@content = File.read path # $ Alert=path1
66
end
77

88
# BAD - File.absolute_path preserves taint
99
def route1
10-
path = File.absolute_path params[:path]
11-
@content = File.read path
10+
path = File.absolute_path params[:path] # $ Source=path2
11+
@content = File.read path # $ Alert=path2
1212
end
1313

1414
# BAD - File.dirname preserves taint
1515
def route2
16-
path = "#{File.dirname(params[:path])}/foo"
17-
@content = File.read path
16+
path = "#{File.dirname(params[:path])}/foo" # $ Source=path3
17+
@content = File.read path # $ Alert=path3
1818
end
1919

2020
# BAD - File.expand_path preserves taint
2121
def route3
22-
path = File.expand_path params[:path]
23-
@content = File.read path
22+
path = File.expand_path params[:path] # $ Source=path4
23+
@content = File.read path # $ Alert=path4
2424
end
2525

2626
# BAD - File.path preserves taint
2727
def route4
28-
path = File.path params[:path]
29-
@content = File.read path
28+
path = File.path params[:path] # $ Source=path5
29+
@content = File.read path # $ Alert=path5
3030
end
3131

3232
# BAD - File.realdirpath preserves taint
3333
def route5
34-
path = File.realdirpath params[:path]
35-
@content = File.read path
34+
path = File.realdirpath params[:path] # $ Source=path6
35+
@content = File.read path # $ Alert=path6
3636
end
3737

3838
# BAD - File.realpath preserves taint
3939
def route6
40-
path = File.realpath params[:path]
41-
@content = File.read path
40+
path = File.realpath params[:path] # $ Source=path7
41+
@content = File.read path # $ Alert=path7
4242
end
4343

4444
# BAD - tainted arguments in any position propagate to the return value of
4545
# File.join
4646
def route7
47-
path = File.join("foo", "bar", "baz", params[:path], "qux")
48-
@content = File.read path
47+
path = File.join("foo", "bar", "baz", params[:path], "qux") # $ Source=path8
48+
@content = File.read path # $ Alert=path8
4949
end
5050

5151
# GOOD - File.basename does not preserve taint
@@ -56,8 +56,8 @@ def route8
5656

5757
# BAD
5858
def route9
59-
path = ActiveStorage::Filename.new(params[:path])
60-
@content = File.read path
59+
path = ActiveStorage::Filename.new(params[:path]) # $ Source=path9
60+
@content = File.read path # $ Alert=path9
6161
end
6262

6363
# GOOD - explicitly sanitized
@@ -68,27 +68,27 @@ def route10
6868

6969
# BAD
7070
def route11
71-
path = ActiveStorage::Filename.new(params[:path])
72-
send_file path
71+
path = ActiveStorage::Filename.new(params[:path]) # $ Source=path10
72+
send_file path # $ Alert=path10
7373
end
7474

7575
# BAD
7676
def route12
77-
path = ActiveStorage::Filename.new(params[:path])
78-
bla (Dir.glob path)
79-
bla (Dir[path])
77+
path = ActiveStorage::Filename.new(params[:path]) # $ Source=path11
78+
bla (Dir.glob path) # $ Alert=path11
79+
bla (Dir[path]) # $ Alert=path11
8080
end
8181

8282
# BAD
8383
def route13
84-
path = ActiveStorage::Filename.new(params[:path])
85-
load(path)
86-
autoload(:MyModule, path)
84+
path = ActiveStorage::Filename.new(params[:path]) # $ Source=path12
85+
load(path) # $ Alert=path12
86+
autoload(:MyModule, path) # $ Alert=path12
8787
end
8888

8989
def require_relative()
90-
path = ActiveStorage::Filename.new(params[:path])
90+
path = ActiveStorage::Filename.new(params[:path]) # $ Source=path13
9191
puts "Debug: require_relative(#{path})"
92-
super(path)
92+
super(path) # $ Alert=path13
9393
end
9494
end

0 commit comments

Comments
 (0)