ruby.lang.security.no-eval.ruby-eval
Community Favorite
semgrep
Author
46,113
Download Count*
License
Use of eval with user-controllable input detected. This can lead to attackers running arbitrary code. Ensure external data does not reach here, otherwise this is a security vulnerability. Consider other ways to do this without eval.
Run Locally
Run in CI
Defintion
rules:
- id: ruby-eval
message: Use of eval with user-controllable input detected. This can lead to
attackers running arbitrary code. Ensure external data does not reach
here, otherwise this is a security vulnerability. Consider other ways to
do this without eval.
severity: WARNING
metadata:
likelihood: HIGH
impact: MEDIUM
confidence: MEDIUM
category: security
cwe2022-top25: true
cwe2021-top25: true
cwe:
- "CWE-94: Improper Control of Generation of Code ('Code Injection')"
owasp:
- A03:2021 - Injection
references:
- https://owasp.org/Top10/A03_2021-Injection
source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_evaluation.rb
subcategory:
- vuln
technology:
- ruby
- rails
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
languages:
- ruby
mode: taint
pattern-sources:
- pattern-either:
- pattern: params
- pattern: cookies
- patterns:
- pattern: |
RubyVM::InstructionSequence.compile(...)
- pattern-not: |
RubyVM::InstructionSequence.compile("...")
pattern-sinks:
- patterns:
- pattern-either:
- pattern: $X.eval
- pattern: $X.class_eval
- pattern: $X.instance_eval
- pattern: $X.module_eval
- pattern: $X.eval(...)
- pattern: $X.class_eval(...)
- pattern: $X.instance_eval(...)
- pattern: $X.module_eval(...)
- pattern: eval(...)
- pattern: class_eval(...)
- pattern: module_eval(...)
- pattern: instance_eval(...)
- pattern-not: $M("...",...)
Examples
no-eval.rb
# ruleid:ruby-eval
Array.class_eval(cookies['tainted_cookie'])
def zen
41
end
# ok:ruby-eval
eval("def zen; 42; end")
puts zen
class Thing
end
a = %q{def hello() "Hello there!" end}
# not user-controllable, this is ok
# ok:ruby-eval
Thing.module_eval(a)
puts Thing.new.hello()
b = params['something']
# ruleid:ruby-eval
Thing.module_eval(b)
# ruleid:ruby-eval
eval(b)
# ruleid:ruby-eval
eval(b,some_binding)
def get_binding(param)
binding
end
b = get_binding("hello")
# ok:ruby-eval
b.eval("some_func")
# ok:ruby-eval
eval("some_func",b)
# ruleid:ruby-eval
eval(params['cmd'],b)
# ruleid:ruby-eval
eval(params.dig('cmd'))
# ruleid:ruby-eval
eval(cookies.delete('foo'))
# ruleid:ruby-eval
RubyVM::InstructionSequence.compile(foo).eval
# ok:ruby-eval
RubyVM::InstructionSequence.compile("1 + 2").eval
iseq = RubyVM::InstructionSequence.compile(foo)
# ruleid:ruby-eval
iseq.eval
iseq = RubyVM::InstructionSequence.compile('num = 1 + 2')
# ok:ruby-eval
iseq.eval
Short Link: https://sg.run/bDwZ