ruby.rails.security.brakeman.check-unsafe-reflection-methods.check-unsafe-reflection-methods
semgrep
Author
unknown
Download Count*
License
Found user-controllable input to a reflection method. This may allow a user to alter program behavior and potentially execute arbitrary instructions in the context of the process. Do not provide arbitrary user input to tap
, method
, or to_proc
Run Locally
Run in CI
Defintion
rules:
- id: check-unsafe-reflection-methods
mode: taint
pattern-sources:
- pattern-either:
- pattern: |
cookies[...]
- patterns:
- pattern: |
cookies. ... .$PROPERTY[...]
- metavariable-regex:
metavariable: $PROPERTY
regex: (?!signed|encrypted)
- pattern: |
params[...]
- pattern: |
request.env[...]
pattern-sinks:
- patterns:
- pattern: $X
- pattern-either:
- pattern-inside: |
$X. ... .to_proc
- patterns:
- pattern-inside: |
$Y.method($Z)
- focus-metavariable: $Z
- patterns:
- pattern-inside: |
$Y.tap($Z)
- focus-metavariable: $Z
- patterns:
- pattern-inside: |
$Y.tap{ |$ANY| $Z }
- focus-metavariable: $Z
message: Found user-controllable input to a reflection method. This may allow a
user to alter program behavior and potentially execute arbitrary
instructions in the context of the process. Do not provide arbitrary user
input to `tap`, `method`, or `to_proc`
languages:
- ruby
severity: ERROR
metadata:
source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_unsafe_reflection_methods.rb
category: security
cwe:
- "CWE-94: Improper Control of Generation of Code ('Code Injection')"
owasp:
- A03:2021 - Injection
technology:
- ruby
- rails
references:
- https://github.com/presidentbeef/brakeman/blob/main/test/apps/rails6/app/controllers/groups_controller.rb
cwe2022-top25: true
subcategory:
- vuln
likelihood: MEDIUM
impact: MEDIUM
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
Examples
check-unsafe-reflection-methods.rb
class GroupsController < ApplicationController
def dynamic_method_invocations
# ruleid: check-unsafe-reflection-methods
params[:method].to_sym.to_proc.call(Kernel)
# ruleid: check-unsafe-reflection-methods
(params[:klass].to_s).method(params[:method]).(params[:argument])
# ruleid: check-unsafe-reflection-methods
Kernel.tap(¶ms[:method].to_sym)
User.method("#{User.first.some_method_thing}_stuff")
user_input_value = params[:my_user_input]
# ruleid: check-unsafe-reflection-methods
anything.tap(&user_input_value.to_sym)
# ruleid: check-unsafe-reflection-methods
anything_else.tap { |thing| thing + user_input_value() }
end
def dynamic_method_invocations_ok
# ok: check-unsafe-reflection-methods
"SomeClass".to_sym.to_proc.call(Kernel)
# ok: check-unsafe-reflection-methods
SomeClass.method("some_method").("some_argument")
# ok: check-unsafe-reflection-methods
Kernel.tap("SomeClass".to_sym)
user_input_value = params[:my_user_input]
# ok: check-unsafe-reflection-methods
user_input_value.tap("some_method")
end
end
Short Link: https://sg.run/dPYd