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?, #model_attribute?, #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
# 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)
    end
  end
  calls.each do |call|
    argument = call.arguments.first
    next if argument.nil?
    ::Spektr.logger.debug "Mass assignment check at #{call.location.line}"
    if user_input?(argument.type, argument.name, call.ast)
      # we check for permit! separately
      next if argument.ast.children[1] == :permit!
      # check for permit with arguments
      next if argument.ast.children[1] == :permit && argument.ast.children[2]
      warn! @target, self, call.location, "Mass assignment"
    end
  end
  @target.find_calls(:permit!).each do |call|
    if call.arguments.none?
      warn! @target, self, call.location, "permit! allows any keys, use it with caution!", :medium
    end
  end
end