A concrete checklist for reviewing a Rails pull request — not generic advice. Items tagged automatable are exactly what a static analyzer like Scryer checks on every commit; the rest still need a human's judgment.
Security code review scales badly as "remember all the OWASP categories" — reviewers are busy, context-switch between PRs, and the same handful of mistakes recur regardless of who's reviewing. A checklist scoped to what actually shows up in Rails PRs, split by what a tool can catch versus what still needs a human, is more useful in practice than a general reference.
?/named bind parameters or the
hash form, never string interpolation into the query text. automatablesystem/backticks/%x{} call includes a request-derived value
without an explicit allowlist. automatableMarshal.load/YAML.unsafe_load/eval runs on data
that ever originates from a request, cookie, or user-editable field. automatableparams that reaches Net::HTTP,
URI.open, File.read/File.join, or send_file
is validated against an allowlist first (SSRF/path traversal). automatableparams are validated against an allowlist, not
passed to redirect_to raw (open redirect). automatableModel.new/update never receives raw params or
params[:model] directly — always through a strong-parameters method with an
explicit .permit list. automatablecreate/update/destroy) has a
visible authorization check somewhere in the controller — but does it check the right
thing for this specific record? That still needs a human. partially automatableModel.find(params[:id])-shaped lookup either scopes to the current
user/tenant, or is behind a class-level authorization filter the reviewer has actually
confirmed applies to this action (IDOR — the single hardest check to fully automate; a
static tool can flag the shape but not confirm the class-level guard actually covers it in
every case). partially automatableskip_before_action silently disables a known authentication filter without
a comment explaining why. automatableconfig.force_ssl isn't set to false in any environment that
serves real traffic. automatablesecure: true (at least in production);
cookies_serializer is :json, never :marshal. automatableX-Frame-Options, X-Content-Type-Options)
aren't explicitly disabled without a documented reason. automatablecredentials: true. automatableconfig.hosts.clear isn't present in production (disables the Host-header
allowlist). automatablesecret_key_base is a string literal anywhere in the
diff — including test fixtures that might get copy-pasted into real config later. automatablebcrypt/Devise,
never MD5/SHA1 alone. automatableJWT.decode calls verify the signature — never verify: false or
algorithm: 'none'. automatableconfig/master.key isn't committed to the repo (check .gitignore
covers it, not just that this specific commit doesn't add it). automatableEverything tagged automatable above is a pattern a static analyzer can reliably flag — that's what a Rails security scanner is for, and it's worth running on every commit rather than re-deriving this list by eye each time. What's genuinely left for a human reviewer: whether the *business logic* around an authorization check is actually correct for this specific feature (not just "a check exists"), whether a new third-party integration's trust boundary is reasonable, and whether a "this is fine because X" comment justifying a flagged pattern is actually true. A tool narrows down where to spend that judgment; it doesn't replace it — see why even the more precise approaches still say "review this," not "confirmed".
gem install scryer
scryer
Every automatable item above maps to one of Scryer's 31 security rules, each with a CWE ID, an OWASP category, and a confidence level — see What Scryer detects for the full rule list, and CI/CD integration to wire it into pull-request review directly (SARIF → GitHub Code Scanning inline annotations).