mirror of
https://github.com/github/codeql.git
synced 2026-04-12 02:24:00 +02:00
Make Code execution query more specific
Only the first argument to eval, instance_eval, send, class_send and module_send is interpreted as Ruby code.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
# Uses of eval and send
|
||||
|
||||
eval("raise \"error\"")
|
||||
eval("raise \"error\"", binding, "file", 1)
|
||||
send("raise", "error")
|
||||
|
||||
a = []
|
||||
a.send("raise", "error")
|
||||
a.send("push", "1")
|
||||
|
||||
class Foo
|
||||
def eval(x)
|
||||
@@ -21,3 +21,6 @@ class Foo
|
||||
end
|
||||
|
||||
Foo.new.send("exit", 1)
|
||||
Foo.new.instance_eval("self.class", "file.rb", 3)
|
||||
Foo.class_eval("def foo; 1; end", "file.rb", 1)
|
||||
Foo.module_eval("def bar; 1; end", "other_file.rb", 2)
|
||||
@@ -59,7 +59,13 @@ open3PipelineCallExecutions
|
||||
| CommandExecution.rb:64:1:64:44 | call to pipeline_start |
|
||||
| CommandExecution.rb:65:1:65:38 | call to pipeline |
|
||||
evalCallCodeExecutions
|
||||
| Eval.rb:3:1:3:23 | call to eval |
|
||||
| Eval.rb:3:1:3:43 | call to eval | Eval.rb:3:6:3:22 | "raise \\"error\\"" |
|
||||
sendCallCodeExecutions
|
||||
| Eval.rb:4:1:4:22 | call to send |
|
||||
| Eval.rb:7:1:7:24 | call to send |
|
||||
| Eval.rb:4:1:4:22 | call to send | Eval.rb:4:6:4:12 | "raise" |
|
||||
| Eval.rb:7:1:7:19 | call to send | Eval.rb:7:8:7:13 | "push" |
|
||||
instanceEvalCallCodeExecutions
|
||||
| Eval.rb:24:1:24:49 | call to instance_eval | Eval.rb:24:23:24:34 | "self.class" |
|
||||
classEvalCallCodeExecutions
|
||||
| Eval.rb:25:1:25:47 | call to class_eval | Eval.rb:25:16:25:32 | "def foo; 1; end" |
|
||||
moduleEvalCallCodeExecutions
|
||||
| Eval.rb:26:1:26:54 | call to module_eval | Eval.rb:26:17:26:33 | "def bar; 1; end" |
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import codeql.ruby.frameworks.StandardLibrary
|
||||
import codeql.ruby.DataFlow
|
||||
|
||||
query predicate subshellLiteralExecutions(SubshellLiteralExecution e) { any() }
|
||||
|
||||
@@ -14,6 +15,18 @@ query predicate open3CallExecutions(Open3Call c) { any() }
|
||||
|
||||
query predicate open3PipelineCallExecutions(Open3PipelineCall c) { any() }
|
||||
|
||||
query predicate evalCallCodeExecutions(EvalCallCodeExecution e) { any() }
|
||||
query DataFlow::Node evalCallCodeExecutions(EvalCallCodeExecution e) { result = e.getCode() }
|
||||
|
||||
query predicate sendCallCodeExecutions(SendCallCodeExecution e) { any() }
|
||||
query DataFlow::Node sendCallCodeExecutions(SendCallCodeExecution e) { result = e.getCode() }
|
||||
|
||||
query DataFlow::Node instanceEvalCallCodeExecutions(InstanceEvalCallCodeExecution e) {
|
||||
result = e.getCode()
|
||||
}
|
||||
|
||||
query DataFlow::Node classEvalCallCodeExecutions(ClassEvalCallCodeExecution e) {
|
||||
result = e.getCode()
|
||||
}
|
||||
|
||||
query DataFlow::Node moduleEvalCallCodeExecutions(ModuleEvalCallCodeExecution e) {
|
||||
result = e.getCode()
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
edges
|
||||
| CodeInjection.rb:3:12:3:17 | call to params : | CodeInjection.rb:6:10:6:13 | code |
|
||||
| CodeInjection.rb:3:12:3:17 | call to params : | CodeInjection.rb:15:20:15:23 | code |
|
||||
| CodeInjection.rb:3:12:3:17 | call to params : | CodeInjection.rb:18:21:18:24 | code |
|
||||
| CodeInjection.rb:3:12:3:17 | call to params : | CodeInjection.rb:18:20:18:23 | code |
|
||||
| CodeInjection.rb:3:12:3:17 | call to params : | CodeInjection.rb:21:21:21:24 | code |
|
||||
nodes
|
||||
| CodeInjection.rb:3:12:3:17 | call to params : | semmle.label | call to params : |
|
||||
| CodeInjection.rb:6:10:6:13 | code | semmle.label | code |
|
||||
| CodeInjection.rb:9:10:9:15 | call to params | semmle.label | call to params |
|
||||
| CodeInjection.rb:15:20:15:23 | code | semmle.label | code |
|
||||
| CodeInjection.rb:18:21:18:24 | code | semmle.label | code |
|
||||
| CodeInjection.rb:18:20:18:23 | code | semmle.label | code |
|
||||
| CodeInjection.rb:21:21:21:24 | code | semmle.label | code |
|
||||
subpaths
|
||||
#select
|
||||
| CodeInjection.rb:6:10:6:13 | code | CodeInjection.rb:3:12:3:17 | call to params : | CodeInjection.rb:6:10:6:13 | code | This code execution depends on $@. | CodeInjection.rb:3:12:3:17 | call to params | a user-provided value |
|
||||
| CodeInjection.rb:9:10:9:15 | call to params | CodeInjection.rb:9:10:9:15 | call to params | CodeInjection.rb:9:10:9:15 | call to params | This code execution depends on $@. | CodeInjection.rb:9:10:9:15 | call to params | a user-provided value |
|
||||
| CodeInjection.rb:15:20:15:23 | code | CodeInjection.rb:3:12:3:17 | call to params : | CodeInjection.rb:15:20:15:23 | code | This code execution depends on $@. | CodeInjection.rb:3:12:3:17 | call to params | a user-provided value |
|
||||
| CodeInjection.rb:18:21:18:24 | code | CodeInjection.rb:3:12:3:17 | call to params : | CodeInjection.rb:18:21:18:24 | code | This code execution depends on $@. | CodeInjection.rb:3:12:3:17 | call to params | a user-provided value |
|
||||
| CodeInjection.rb:18:20:18:23 | code | CodeInjection.rb:3:12:3:17 | call to params : | CodeInjection.rb:18:20:18:23 | code | This code execution depends on $@. | CodeInjection.rb:3:12:3:17 | call to params | a user-provided value |
|
||||
| CodeInjection.rb:21:21:21:24 | code | CodeInjection.rb:3:12:3:17 | call to params : | CodeInjection.rb:21:21:21:24 | code | This code execution depends on $@. | CodeInjection.rb:3:12:3:17 | call to params | a user-provided value |
|
||||
|
||||
@@ -8,6 +8,9 @@ class UsersController < ActionController::Base
|
||||
# BAD
|
||||
eval(params)
|
||||
|
||||
# GOOD - user input is in second argument, which is not evaluated as Ruby code
|
||||
send(:sanitize, params[:code])
|
||||
|
||||
# GOOD
|
||||
Foo.new.bar(code)
|
||||
|
||||
@@ -25,6 +28,12 @@ class UsersController < ActionController::Base
|
||||
# GOOD
|
||||
eval("foo")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sanitize(code)
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class Foo
|
||||
|
||||
Reference in New Issue
Block a user