Static application security testing (SAST) for Ruby on Rails, explained — what it checks, how it differs from a pen test, and where a given tool sits on the precision/coverage tradeoff.
A Rails security scanner is a program that reads your application's source code and flags patterns known to cause vulnerabilities — without running the app, without a database, and without anyone attacking it. That's the category name for what's more formally called SAST for Rails ("static application security testing," applied to Ruby on Rails specifically): the analysis happens on source text/syntax, statically, before deployment — as opposed to DAST (dynamic testing against a running app) or a manual pen test (a human actively trying to break in). All three answer a different question; a mature security program usually uses more than one.
Concretely, a Rails-aware scanner walks your controllers, models, views, and config files looking for specific dangerous shapes — the kind of Ruby security audit a human reviewer would do by hand, automated and run on every commit instead of once a quarter:
where("name = '#{params[:name]}'")), command injection via system/
backticks with unsanitized input, unsafe deserialization (Marshal.load on
untrusted data).Model.new(params[:model])
with no .permit), missing authorization checks on write actions, IDOR (an ID from
params reaching Model.find with no ownership check).secure flag, the Marshal cookie serializer (a known RCE vector), CORS wildcard
origins combined with credentials, disabled default security headers.secret_key_base,
weak hashing (MD5/SHA1 for anything security-sensitive), insecure JWT usage (signature
verification disabled, alg: none).params.Every Rails security scanner has to pick a point on a real tradeoff, and it's worth knowing which side a given tool is on before you trust its output:
params reference merely appear together, without tracing whether the
value actually reaches the sink through that path. Faster, needs no framework boot or call
graph, but a real precision gap on the harder checks — every finding is "review this," not "this
is definitely exploitable." This is what Scryer does; see Taint analysis vs. heuristic
pattern matching for the honest tradeoff in detail.Neither approach is strictly better — a data-flow scanner is more trustworthy per-finding but typically only covers security; a heuristic scanner can run fast enough, and cheaply enough, to also cover performance and dependency risk in the same pass and rank all of it together, which is Scryer's actual differentiator (see the front page).
Scryer is a heuristic Rails security scanner and static analysis tool, with the honest scope
that implies: 31 security rules covering the categories above, each tagged with
a CWE ID, an OWASP Top 10 (2021) category, and a confidence level — plus performance heuristics
(N+1 queries, missing pagination), a live dependency audit against OSV.dev, and duplicate-code detection, all ranked together by
severity so a scan ends with one answer to "what's most worth fixing first." It uses Ruby's
stdlib Ripper parser directly — no Rails boot, no database, zero runtime
dependencies beyond Ruby itself.
gem install scryer
scryer
| Capability | Scryer | RuboCop | Brakeman | bundler-audit |
|---|---|---|---|---|
| Rails security scanning (SAST) | ✅ heuristic | ❌ | ✅ taint/data-flow | ❌ |
| Dependency security | ✅ | ❌ | ❌ | ✅ |
| Performance heuristics | ✅ | Partial | ❌ | ❌ |
| Style/lint conventions | Partial | ✅ | ❌ | ❌ |
| Cross-category severity ranking | ✅ | ❌ | ❌ | ❌ |
Full breakdown with footnotes in the README.