Skip to content

Commit 3461404

Browse files
committed
add basic support for arrays
1 parent 0f2a48f commit 3461404

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

ruby/ql/lib/codeql/ruby/security/UnsafeCodeConstructionCustomizations.qll

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
* well as extension points for adding your own.
55
*/
66

7-
private import codeql.ruby.DataFlow
7+
private import ruby
88
private import codeql.ruby.ApiGraphs
99
private import codeql.ruby.frameworks.core.Gem::Gem as Gem
10-
private import codeql.ruby.AST as Ast
1110
private import codeql.ruby.Concepts as Concepts
1211

1312
/**
@@ -58,6 +57,25 @@ module UnsafeCodeConstruction {
5857
)
5958
}
6059

60+
/**
61+
* A string constructed using a `.join(...)` call, where the resulting string ends up being executed as code.
62+
*/
63+
class ArrayJoin extends Sink {
64+
Concepts::CodeExecution s;
65+
DataFlow::CallNode call;
66+
67+
ArrayJoin() {
68+
call.getMethodName() = "join" and
69+
call.getNumberOfArguments() = 1 and // any string. E.g. ";" or "\n".
70+
call = getANodeExecutedAsCode(s) and
71+
this = call.getReceiver()
72+
}
73+
74+
override DataFlow::Node getCodeSink() { result = s }
75+
76+
override string getSinkType() { result = "array" }
77+
}
78+
6179
/**
6280
* A string constructed from a string-literal (e.g. `"foo #{sink}"`),
6381
* where the resulting string ends up being executed as a code.

ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@ edges
22
| impl/unsafeCode.rb:2:12:2:17 | target : | impl/unsafeCode.rb:3:17:3:25 | #{...} |
33
| impl/unsafeCode.rb:7:12:7:12 | x : | impl/unsafeCode.rb:8:30:8:30 | x |
44
| impl/unsafeCode.rb:12:12:12:12 | x : | impl/unsafeCode.rb:13:33:13:33 | x |
5+
| impl/unsafeCode.rb:28:17:28:22 | my_arr : | impl/unsafeCode.rb:29:10:29:15 | my_arr |
56
nodes
67
| impl/unsafeCode.rb:2:12:2:17 | target : | semmle.label | target : |
78
| impl/unsafeCode.rb:3:17:3:25 | #{...} | semmle.label | #{...} |
89
| impl/unsafeCode.rb:7:12:7:12 | x : | semmle.label | x : |
910
| impl/unsafeCode.rb:8:30:8:30 | x | semmle.label | x |
1011
| impl/unsafeCode.rb:12:12:12:12 | x : | semmle.label | x : |
1112
| impl/unsafeCode.rb:13:33:13:33 | x | semmle.label | x |
13+
| impl/unsafeCode.rb:28:17:28:22 | my_arr : | semmle.label | my_arr : |
14+
| impl/unsafeCode.rb:29:10:29:15 | my_arr | semmle.label | my_arr |
1215
subpaths
1316
#select
1417
| impl/unsafeCode.rb:3:17:3:25 | #{...} | impl/unsafeCode.rb:2:12:2:17 | target : | impl/unsafeCode.rb:3:17:3:25 | #{...} | This string interpolation which depends on $@ is later $@. | impl/unsafeCode.rb:2:12:2:17 | target | library input | impl/unsafeCode.rb:3:5:3:27 | call to eval | interpreted as code |
1518
| impl/unsafeCode.rb:8:30:8:30 | x | impl/unsafeCode.rb:7:12:7:12 | x : | impl/unsafeCode.rb:8:30:8:30 | x | This string format which depends on $@ is later $@. | impl/unsafeCode.rb:7:12:7:12 | x | library input | impl/unsafeCode.rb:8:5:8:32 | call to eval | interpreted as code |
1619
| impl/unsafeCode.rb:13:33:13:33 | x | impl/unsafeCode.rb:12:12:12:12 | x : | impl/unsafeCode.rb:13:33:13:33 | x | This string format which depends on $@ is later $@. | impl/unsafeCode.rb:12:12:12:12 | x | library input | impl/unsafeCode.rb:13:5:13:35 | call to eval | interpreted as code |
20+
| impl/unsafeCode.rb:29:10:29:15 | my_arr | impl/unsafeCode.rb:28:17:28:22 | my_arr : | impl/unsafeCode.rb:29:10:29:15 | my_arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:28:17:28:22 | my_arr | library input | impl/unsafeCode.rb:29:5:29:27 | call to eval | interpreted as code |

ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/impl/unsafeCode.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,11 @@ def send_stuff(x)
2424
def named_code(code)
2525
foo.send("def \n #{code} \n end") # OK - parameter is named code
2626
end
27+
28+
def joinStuff(my_arr)
29+
eval(my_arr.join("\n")) # NOT OK
30+
end
31+
32+
# TODO: [x, y].join("\n") is not yet supported
33+
# TODO: list << element.
2734
end

0 commit comments

Comments
 (0)