Framework audits/Rails

Rails Security Audit

What should a Rails security audit check?

Rails protects against most common web vulnerabilities by convention, so an audit looks for places the conventions were suspended. The findings that matter are permit-all strong parameters, string interpolation inside where clauses, CSRF verification skipped on controllers that accept writes, and credentials handled outside the encrypted store.

Because Rails secures by convention rather than configuration, its vulnerabilities tend to be single lines that opt out — one permit-all, one skip-forgery-protection — rather than settings left at a bad default.

Where Rails codebases actually break

These are patterns we look for in code produced this way — not flaws in Rails itself. Each names the check that finds it.

Strong parameters permitting everything

Strong parameters exist to whitelist what a request may set. A controller that permits all keys restores the mass-assignment vulnerability the feature was introduced to prevent, and it is a single expressive line that reads as convenience rather than as a security decision.

Detected by: Unvalidated request input

Interpolation inside a where clause

ActiveRecord parameterises when given a placeholder and an argument. Passing an interpolated string instead — which is shorter and works identically in testing — puts the request value directly into the SQL. This is the dominant source of injection in Rails codebases.

Detected by: SQL string concatenation

CSRF verification skipped on a writing controller

Forgery protection is enabled by default, and skipping it is a one-line change usually made to unblock an API client or a webhook. Where that controller also accepts state-changing requests from browser sessions, the skip removes protection from those too.

Detected by: Unvalidated request input

Credentials outside the encrypted store

Rails provides an encrypted credentials file precisely so secrets can be committed safely. Values placed in plain initialisers or checked-in environment files instead are in history permanently, and inherited Rails applications frequently predate the encrypted store entirely.

Detected by: Hardcoded secret value

Auditing a Rails codebase: the short list

  • Grep controllers for permit-all parameter calls and replace each with an explicit attribute list
  • Find every where clause built with interpolation and convert it to a placeholder with arguments
  • List every controller that skips forgery protection and confirm none accepts session-authenticated writes
  • Confirm secrets live in the encrypted credentials store, and rotate anything found in plain files or history
  • Check that developer-facing routes and detailed error pages are not reachable in production

Scan your Rails codebase

Every check named above runs automatically. Free on public repositories, no signup, results in under three minutes — with the file and line for each finding.

Frequently asked questions

Is Rails secure by default?

Largely yes. CSRF protection, parameterised queries, output escaping and strong parameters are all on by convention. Rails vulnerabilities are usually opt-outs — a single line that suspends a protection for a reason that made sense at the time and was never revisited.

How does SQL injection happen in Rails?

Through string interpolation in query methods. ActiveRecord parameterises when given a placeholder and a separate argument, but interpolating the value into the string bypasses that entirely, and the two forms behave identically in testing.

Where should secrets live in a Rails app?

In the encrypted credentials store, which exists so they can be committed safely, or in environment variables. Anything that has sat in a plain initialiser or a committed environment file should be treated as exposed and rotated, since removal does not clear git history.

Related reading