check_forgery_setting.rb 3.2 KB
Newer Older
J
Justin Collins 已提交
1
require 'brakeman/checks/base_check'
J
Justin 已提交
2

3 4 5 6
#Checks that +protect_from_forgery+ is set in the ApplicationController.
#
#Also warns for CSRF weakness in certain versions of Rails:
#http://groups.google.com/group/rubyonrails-security/browse_thread/thread/2d95a3cc23e03665
J
Justin Collins 已提交
7 8
class Brakeman::CheckForgerySetting < Brakeman::BaseCheck
  Brakeman::Checks.add self
J
Justin 已提交
9

10 11
  @description = "Verifies that protect_from_forgery is enabled in ApplicationController"

J
Justin 已提交
12 13
  def run_check
    app_controller = tracker.controllers[:ApplicationController]
14 15 16

    return unless ancestor? app_controller, :"ActionController::Base"

17
    if tracker.config[:rails][:action_controller] and
J
Justin 已提交
18 19 20
      tracker.config[:rails][:action_controller][:allow_forgery_protection] == Sexp.new(:false)

      warn :controller => :ApplicationController,
21
        :warning_type => "Cross-Site Request Forgery",
J
Justin Collins 已提交
22
        :warning_code => :csrf_protection_disabled,
23
        :message => "Forgery protection is disabled",
24
        :confidence => CONFIDENCE[:high],
25
        :file => app_controller[:files].first
J
Justin 已提交
26 27 28

    elsif app_controller and not app_controller[:options][:protect_from_forgery]

29 30
      warn :controller => :ApplicationController,
        :warning_type => "Cross-Site Request Forgery",
J
Justin Collins 已提交
31
        :warning_code => :csrf_protection_missing,
32
        :message => "'protect_from_forgery' should be called in ApplicationController",
33
        :confidence => CONFIDENCE[:high],
34
        :file => app_controller[:files].first
35 36

    elsif version_between? "2.1.0", "2.3.10"
37 38

      warn :controller => :ApplicationController,
39
        :warning_type => "Cross-Site Request Forgery",
J
Justin Collins 已提交
40
        :warning_code => :CVE_2011_0447,
41
        :message => "CSRF protection is flawed in unpatched versions of Rails #{tracker.config[:rails_version]} (CVE-2011-0447). Upgrade to 2.3.11 or apply patches as needed",
42
        :confidence => CONFIDENCE[:high],
43
        :gem_info => gemfile_or_environment,
44
        :link_path => "https://groups.google.com/d/topic/rubyonrails-security/LZWjzCPgNmU/discussion"
45 46 47

    elsif version_between? "3.0.0", "3.0.3"

48
      warn :controller => :ApplicationController,
49
        :warning_type => "Cross-Site Request Forgery",
J
Justin Collins 已提交
50
        :warning_code => :CVE_2011_0447,
51
        :message => "CSRF protection is flawed in unpatched versions of Rails #{tracker.config[:rails_version]} (CVE-2011-0447). Upgrade to 3.0.4 or apply patches as needed",
52
        :confidence => CONFIDENCE[:high],
53
        :gem_info => gemfile_or_environment,
54
        :link_path => "https://groups.google.com/d/topic/rubyonrails-security/LZWjzCPgNmU/discussion"
55 56 57 58 59 60 61 62 63 64 65
    elsif version_between? "4.0.0", "100.0.0" and forgery_opts = app_controller[:options][:protect_from_forgery]

      unless forgery_opts.is_a?(Array) and sexp?(forgery_opts.first) and hash_access(forgery_opts.first.first_arg, :with).value == :exception
        warn :controller => :ApplicationController,
          :warning_type => "Cross-Site Request Forgery",
          :warning_code => :csrf_not_protected_by_raising_exception,
          :message => "protect_from_forgery should be configured with 'with: :exception'",
          :confidence => CONFIDENCE[:med],
          :file => app_controller[:files].first,
          :link_path => "blog post link?"
      end
J
Justin 已提交
66 67 68
    end
  end
end