Rails GuardDog: Advanced Security Scanner for Rails
Introduction
Today I'm excited to announce Rails GuardDog v0.1.0 — an open-source security
scanner for Rails that goes beyond traditional tools like Brakeman.
While Brakeman is excellent for catching basic Rails vulnerabilities, Rails GuardDog
focuses on newer vulnerability classes that most tools miss: AI/LLM prompt injection,
DoS/ReDoS patterns, supply chain attacks, and more.
The Problem
Modern Rails applications face new security challenges:
- AI/LLM Integration - How do you prevent prompt injection when integrating with ChatGPT, Claude, or Anthropic?
- ReDoS Attacks - Catastrophic backtracking in regex can bring down your app
- Supply Chain Attacks - Typosquatted gems that look like popular libraries
- IDOR Gaps - Objects accessible without proper authorization checks
- Advanced Secrets - Hardcoded API keys that Brakeman misses
Rails GuardDog detects all of these.
What is Rails GuardDog?
Rails GuardDog is a lightweight gem that adds comprehensive security scanning
directly to your Rails applications.
12 Security Checkers
- SQL Injection - String interpolation in queries
- XSS - Unescaped output in views
- CSRF - Disabled protection verification
-
Mass Assignment -
permit!vulnerabilities (fixes Brakeman #1942, #1918) - Open Redirect - User input in redirects
- Hardcoded Secrets - API keys, tokens, passwords (always-on, fixes #1989)
- DoS/ReDoS - Unbounded queries, dangerous regex patterns
- IDOR - Object access without authorization
- AI/LLM Prompt Injection - User input flowing to LLMs
- Rate Limiting - Missing rack-attack configuration
- Supply Chain - Typosquatted gems using Levenshtein distance
- GraphQL - Missing field-level authorization
Features
- 📊 Multiple report formats: Console, HTML, JSON
- 🔍 AST-based analysis: Uses parser gem for deep code understanding
- ⚡ Async support: Built-in Sidekiq integration
- 📈 Zero dependencies: Only requires parser and ast gems
- 🚀 Production-ready: Tested and battle-ready
- 📝 CWE/OWASP mappings: Every finding includes vulnerability mappings
Installation
gem 'rails-guarddog'
bundle install
Quick Start
# Scan your Rails app
rake guarddog:scan
# Generate HTML + JSON reports
rake guarddog:report
# CI/CD integration (exits 1 if critical found)
rake guarddog:ci
Example Output
====================================================================
Rails GuardDog Security Report
CRITICAL
Mass Assignment — permit! allows ALL parameters
app/controllers/users_controller.rb:15
Fix: Use permit(:name, :email, :age)
AI Injection — User input in LLM prompt
app/services/chat_service.rb:42
Fix: Sanitize: prompt = 'Template: ' + sanitize(params[:text])
HIGH
DoS: Unbounded query without limit
app/controllers/posts_controller.rb:5
Fix: Add .limit(100) or use pagination
Comparison with Brakeman
| Feature | Brakeman | Rails GuardDog |
|---|---|---|
| SQL Injection | ✅ | ✅ Enhanced |
| XSS | ✅ | ✅ Extended |
| CSRF | ✅ | ✅ Full |
| Mass Assignment | ✅ Partial | ✅ Fixed |
| Secrets | ⚠️ Optional | ✅ Always-on |
| DoS/ReDoS | ❌ | ✅ NEW |
| IDOR | ❌ | ✅ NEW |
| AI Injection | ❌ | ✅ ORIGINAL |
| Supply Chain | ❌ | ✅ ORIGINAL |
| GraphQL | ❌ | ✅ BONUS |
Why I Built This
At [Your Company/Team], we encountered vulnerabilities that Brakeman couldn't catch:
- A developer passed user input directly to Claude without sanitization
- We found dangerous regex patterns that could cause ReDoS attacks
- A typosquatted gem almost made it into production
- Several GraphQL resolvers lacked authorization checks
I decided to build a tool that catches these modern vulnerabilities.
Real-World Example: AI Injection
Here's a vulnerability Rails GuardDog catches:
# ❌ DANGEROUS - User input flows directly to LLM
def summarize
text = params[:text]
response = OpenAI.create_message(
model: "gpt-4",
messages: [
{ role: "user", content: "Summarize: #{text}" }
]
)
end
# ✅ SAFE - Sanitized input
def summarize
text = sanitize(params[:text]).first(500)
response = OpenAI.create_message(
model: "gpt-4",
messages: [
{ role: "system", content: "You are helpful." },
{ role: "user", content: "Summarize: #{text}" }
]
)
end
Rails GuardDog would flag the first example immediately.
Configuration
# config/initializers/guarddog.rb
Rails.application.config.guarddog.enabled_checkers = %w[
sql_injection xss csrf mass_assignment secrets
ai_injection idor dos rate_limit
]
Rails.application.config.guarddog.fail_on_severity = :critical
CI/CD Integration
# .github/workflows/security.yml
name: Security Scan
on: [push, pull_request]
jobs:
guarddog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
- name: Run GuardDog
run: bundle exec rake guarddog:ci
- name: Upload report
uses: actions/upload-artifact@v3
with:
name: guarddog-report
path: guarddog_report.*
Get Started
Rails GuardDog is available now on RubyGems:
gem 'rails-guarddog'
- RubyGems: https://rubygems.org/gems/rails-guarddog
- GitHub: https://github.com/yourusername/rails-guarddog
- Issues: https://github.com/yourusername/rails-guarddog/issues
- MIT License: Open source and free
Next Steps
- Try it in your Rails app:
gem 'rails-guarddog' - Run:
rake guarddog:scan - Check the HTML report:
rake guarddog:report - Add to CI:
rake guarddog:ci - Share feedback: GitHub issues
Contributing
Found a bug? Have an idea? Contributions welcome!
- Submit issues: https://github.com/yourusername/rails-guarddog/issues
- Open PRs: https://github.com/yourusername/rails-guarddog/pulls
- Star on GitHub ⭐
Questions?
Drop a comment below or reach out on GitHub!
Rails GuardDog v0.1.0 is production-ready and available now. 🐕