mirror of
https://github.com/github/codeql.git
synced 2025-12-20 10:46:30 +01:00
Module#const_get takes a single string argument and interprets it as the
name of a constant. It then looks up the constant and returns its value.
Object.const_get("Math::PI")
# => 3.141592653589793
By itself, this method is not as dangerous as e.g. eval, but if the
value returned is a class that is then instantiated, this can allow an
attacker to instantiate arbitrary Ruby classes.
As a result, I think it's safe to say that any remote input flowing into
this call is a potential vulnerability. A real-world example of this is
https://github.com/advisories/GHSA-52p9-v744-mwjj.
66 lines
793 B
Ruby
66 lines
793 B
Ruby
class UsersController < ActionController::Base
|
|
def create
|
|
code = params[:code]
|
|
|
|
# BAD
|
|
eval(code)
|
|
|
|
# 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)
|
|
|
|
# BAD
|
|
Foo.class_eval(code)
|
|
|
|
# BAD
|
|
Foo.module_eval(code)
|
|
|
|
# GOOD
|
|
Bar.class_eval(code)
|
|
|
|
# BAD
|
|
const_get(code)
|
|
|
|
# BAD
|
|
Foo.const_get(code)
|
|
|
|
# GOOD
|
|
Bar.const_get(code)
|
|
end
|
|
|
|
def update
|
|
# GOOD
|
|
eval("foo")
|
|
end
|
|
|
|
private
|
|
|
|
def sanitize(code)
|
|
true
|
|
end
|
|
end
|
|
|
|
class Foo
|
|
def eval(x)
|
|
true
|
|
end
|
|
|
|
def bar(x)
|
|
eval(x)
|
|
end
|
|
end
|
|
|
|
class Bar
|
|
def self.class_eval(x)
|
|
true
|
|
end
|
|
|
|
def self.const_get(x)
|
|
true
|
|
end
|
|
end |