Class: RuboCop::Cop::RosettAi::UnsafeSend

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/rosett_ai/unsafe_send.rb

Overview

Flags send, public_send, and __send__ calls with non-literal method names. Dynamic method dispatch with user input can lead to arbitrary method execution.

Safe patterns validate the method name against an allowlist before calling send.

Examples:

# bad
object.send(user_input)
object.public_send(params[:method])
receiver.__send__(dynamic_method)

# good - validate against allowlist first
ALLOWED_METHODS = %w[foo bar].freeze
raise ArgumentError unless ALLOWED_METHODS.include?(method_name)
object.send(method_name)

# good - literal method names
object.send(:known_method)
object.public_send('safe_method')

Constant Summary collapse

MSG =
'Avoid `%<method>s` with non-literal method names. ' \
'Validate against an allowlist first to prevent arbitrary method execution.'
SEND_METHODS =
[:send, :public_send, :__send__].freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



42
43
44
45
46
# File 'lib/rubocop/cop/rosett_ai/unsafe_send.rb', line 42

def on_send(node)
  send_with_dynamic?(node) do |method_name, _arg|
    add_offense(node, message: format(MSG, method: method_name))
  end
end

#send_with_dynamic?(node) ⇒ Object

send/public_send/send with any argument that is not a literal symbol or string



38
39
40
# File 'lib/rubocop/cop/rosett_ai/unsafe_send.rb', line 38

def_node_matcher :send_with_dynamic?, <<~PATTERN
  (send _ ${:send :public_send :__send__} $!{sym str} ...)
PATTERN