Class: Scryer::Rules::AuthenticationBypassRule
- Inherits:
-
Scryer::Rule
- Object
- Scryer::Rule
- Scryer::Rules::AuthenticationBypassRule
- Defined in:
- lib/scryer/rules/authentication_bypass_rule.rb
Overview
Flags a controller class that calls skip_before_action/
skip_action_callback naming a common authentication filter
(authenticate_user!, authenticate!, ...) — same shape and reasoning
as CsrfProtectionRule, just for auth filters instead of CSRF: skipping
one is sometimes correct (a public endpoint, a webhook) but is also a
common way to accidentally leave an action reachable without login,
especially with a broad except:/no scoping at all.
Constant Summary collapse
- SKIP_METHODS =
%w[skip_before_action skip_action_callback skip_before_filter].freeze
- AUTH_FILTER_NAMES =
%w[ authenticate_user! authenticate! authenticate_admin! authenticate_account! require_login require_authentication authorize_request ].freeze
Instance Attribute Summary
Attributes inherited from Scryer::Rule
Instance Method Summary collapse
Methods inherited from Scryer::Rule
Constructor Details
This class inherits a constructor from Scryer::Rule
Instance Method Details
#scan ⇒ Object
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 48 |
# File 'lib/scryer/rules/authentication_bypass_rule.rb', line 22 def scan findings = [] Ast.each_node(sexp) do |node| next unless Ast.tagged?(node, :class) class_name = Ast.ident_text(node[1].is_a?(Array) ? node[1][1] : nil) next unless class_name.to_s.end_with?("Controller") each_skip_call(node[3]).each do |skip_node, filter_name| line = Ast.line_of(skip_node) findings << finding( line: line, message: "`#{class_name}` skips the `#{filter_name}` authentication filter " \ "(`#{skip_call_method(skip_node)} :#{filter_name}`) — every action this " \ "applies to is reachable without logging in unless something else in " \ "this controller re-checks authentication.", suggested_fix: "If this is genuinely a public action (a webhook, a login/signup " \ "page), scope the skip tightly with `only: [:action_name]` rather " \ "than leaving it unscoped or using a broad `except:`. If it's not " \ "meant to be public, remove the skip." ) end end findings end |