Class: Spektr::Checks::MassAssignment

Inherits:
Base
  • Object
show all
Defined in:
lib/spektr/checks/mass_assignment.rb

Instance Attribute Summary

Attributes inherited from Base

#name

Instance Method Summary collapse

Methods inherited from Base

#app_version_between?, #dupe?, #full_receiver, #model_attribute?, #receivers_for, #should_run?, #target_affected?, #user_input?, #version_affected, #version_between?, #warn!

Constructor Details

#initialize(app, target) ⇒ MassAssignment

TODO: Make this better



6
7
8
9
10
11
# File 'lib/spektr/checks/mass_assignment.rb', line 6

def initialize(app, target)
  super
  @name = "Mass Assignment"
  @type = "Input Validation"
  @targets = ["Spektr::Targets::Controller"]
end

Instance Method Details

#runObject



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/spektr/checks/mass_assignment.rb', line 13

def run
  return unless super
  model_names = @app.models.collect(&:name)
  calls = []
  model_names.each do |receiver|
    [:new, :build, :create].each do |method|
      calls.concat @target.find_calls(method, receiver&.to_sym)
    end
  end
  calls.each do |call|
    argument = call.arguments&.arguments&.first
    next if argument.nil?
    ::Spektr.logger.debug "Mass assignment check at #{call.location.start_line}"
    next unless user_input?(argument)
    if argument.type == :local_variable_read_node
      variable = @target.lvars.find do |n|
        n.name == argument.name
      end
      param = variable.value
    else
      param = argument
    end
    # we check for permit! separately
    next if param.respond_to?(:name) && param.name == :permit!
    # check for permit with arguments
    next if param.respond_to?(:name) && param.name == :permit && param.arguments
    warn! @target, self, call.location, "Mass assignment"
  end
  @target.find_calls(:permit!).each do |call|
    unless call.arguments
      warn! @target, self, call.location, "permit! allows any keys, use it with caution!", :medium
    end
  end
end