Class: Scryer::Rules::CsrfProtectionRule

Inherits:
Scryer::Rule show all
Defined in:
lib/scryer/rules/csrf_protection_rule.rb

Overview

Flags a controller class named *Controller that calls skip_before_action :verify_authenticity_token without that same file (or, best-effort, without any protect_from_forgery call visible in it) — skipping CSRF verification on a controller that isn't clearly API-only (no < ActionController::API / ActionController::Base used alongside explicit null_session) is a common way to accidentally disable CSRF protection app-wide for that controller's actions.

Instance Attribute Summary

Attributes inherited from Scryer::Rule

#file, #sexp, #source

Instance Method Summary collapse

Methods inherited from Scryer::Rule

inherited, #initialize

Constructor Details

This class inherits a constructor from Scryer::Rule

Instance Method Details

#scanObject



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
47
# File 'lib/scryer/rules/csrf_protection_rule.rb', line 19

def scan
  findings = []

  Ast.each_node(sexp) do |node|
    next unless Ast.tagged?(node, :class)

    class_name = Ast.class_name(node[1])
    next unless class_name.to_s.end_with?("Controller")

    body = node[3]
    skip_node = find_skip_verify(body)
    next unless skip_node

    has_null_session_pattern = each_descendant_call_names(body).any? do |name|
      name == "protect_from_forgery"
    end
    next if has_null_session_pattern # they've explicitly configured an alternative

    line = Ast.line_of(skip_node)
    findings << finding(
      line: line,
      severity: scoped_to_specific_actions?(skip_node) ? "info" : self.class.default_severity,
      message: scoped_message(class_name, skip_node),
      suggested_fix: scoped_suggested_fix(skip_node)
    )
  end

  findings
end