RailsSecurityTagger
Inherits FrameworkTagger < FileHelper < Tagger < Reference < Object
Rails-specific security tagger.
ruby_auth already classifies authentication (Devise/Pundit/CanCanCan/…),
so this tagger covers the other Rails controller-level security signals
that map cleanly onto an action and are deviations from the framework
default — i.e. worth a reviewer's attention rather than ambient noise:
- csrf-protection — CSRF disabled (
skip_before_action :verify_authenticity_token,skip_forgery_protection) or downgraded (protect_from_forgery with: :null_session). Rails protects every state-changing request by default, so an explicit opt-out is the interesting case. - mass-assignment — Strong Parameters bypassed (
params.permit!,params.to_unsafe_h, or a rawparams[:x]hash handed to a model writer likeModel.new(params[:user])). - rate-limit — Rails 8 native
rate_limitthrottle on the action.
Like ruby_auth, detection is single-file and line-based: it walks the
controller the action lives in. Cross-file concerns (a null_session
base controller inherited by children, a Rack::Attack initializer) are
out of scope by design — those live outside the action's own file.
Constants
Every pattern check_csrf tests a line against.
Class-level macros that turn CSRF verification OFF for (some) actions.
Per-line flags for the two class-macro walks, computed once per file.
check_csrf and check_rate_limit each walk from an action back to its
enclosing class, so a controller with N actions had every line above
them stripped and regex-tested 2N times. None of that depends on the
action — only macro_applies? does, and it only runs on a line whose
pattern already matched — so classify each line once and let the walks
skip the lines no pattern can match.
protect_from_forgery with: :null_session keeps the filter but lets a
forged request through with a blank session instead of rejecting it —
the usual choice for token/API controllers, and worth flagging because
cookie-session callers lose CSRF rejection.
Strong-Parameters escape hatches in an action body.
A raw params[:x] hash passed straight into a model writer (no
intervening .permit). find/where take a scalar id, so they are
deliberately excluded — only attribute-setting writers are risky.
Rails 8 rate_limit to: N, within: T[, only:/except:] declared like a
before_action at class scope.