Rails GuardDog 🐕
Production-grade security scanner for Rails applications. Beyond brakeman — detects AI injection, DoS patterns, supply chain attacks, GraphQL authorization gaps, and more.
✨ Why Rails GuardDog?
| Feature | Brakeman | bundler-audit | rack-attack | GuardDog |
|---|---|---|---|---|
| SQL Injection | ✅ | - | - | ✅ Enhanced |
| XSS Detection | ✅ | - | - | ✅ Extended |
| CSRF Checks | ✅ | - | - | ✅ Full |
| Mass Assignment | ✅ Partial | - | - | ✅ permit! fixed |
| Hardcoded Secrets | ⚠️ Optional | - | - | ✅ Always-on |
| Open Redirect | ✅ | - | - | ✅ |
| DoS/ReDoS | ❌ | - | - | ✅ NEW |
| IDOR | ❌ | - | - | ✅ NEW |
| AI Injection | ❌ | - | - | ✅ ORIGINAL |
| Supply Chain | ❌ | ⚠️ Limited | - | ✅ Typosquatting |
| Rate Limiting | ❌ | - | ⚠️ Config only | ✅ Audit |
| GraphQL Auth | ❌ | - | - | ✅ BONUS |
📊 Stats
| Metric | Value |
|---|---|
| Version | |
| Total Downloads | |
| Security Checkers | 12 |
| Report Formats | 3 (Console, HTML, JSON) |
| Dependencies | 2 (parser, ast) |
| Lines of Code | ~2,000 |
| License | MIT |
🚀 Quick Start
Installation
Add to your Gemfile:
gem 'rails-guarddog'
Then run:
bundle install
First Scan
# See results in terminal
rake guarddog:scan
# Generate HTML + JSON reports
rake guarddog:report
# CI/CD integration (exits 1 if critical found)
rake guarddog:ci
🔒 Security Checkers (12 Total)
Authentication & Authorization
- IDOR Detection — Object access without ownership verification
- GraphQL Authorization — Missing field-level auth checks
- Open Redirect — User input in
redirect_towithout validation - Rate Limiting Audit — Missing rack-attack configuration
Injection Attacks
- SQL Injection — String interpolation in queries
- XSS (Cross-Site Scripting) — Unescaped user input in views
- AI/LLM Prompt Injection — User input flowing directly to LLMs (ORIGINAL)
Data Protection
- CSRF Protection — Disabled without documented reason
- Mass Assignment —
permit!vulnerabilities - Hardcoded Secrets — API keys, tokens, passwords in code (ALWAYS-ON)
Resource Management
- DoS/ReDoS — Unbounded queries, dangerous regex patterns
- Supply Chain — Typosquatted gems using Levenshtein distance (ORIGINAL)
📊 Example Output
Console Report
============================================================
Rails GuardDog Security Report
============================================================
[CRITICAL] (5 findings)
Mass Assignment — permit! allows ALL parameters
app/controllers/users_controller.rb:15
Fix: Use permit(:name, :email, :age) for specific fields
AI Injection — User input in LLM prompt
app/services/chat_service.rb:42
Fix: Sanitize: prompt = 'Template: ' + sanitize(params[:text])
Hardcoded Secret — API Key detected
config/initializers/api.rb:3
Fix: Move to Rails.application.credentials
[HIGH] (8 findings)
DoS: Unbounded query without limit
app/controllers/posts_controller.rb:5
Fix: Add .limit(100) or use pagination
ReDoS: Dangerous regex pattern
app/models/validator.rb:22
Fix: Simplify regex or add timeout
============================================================
Total findings: 15 | Critical: 5 | High: 8
============================================================
HTML Report
- 📊 Interactive dashboard with severity filtering
- 🎨 Color-coded findings (CRITICAL, HIGH, MEDIUM, LOW)
- 💡 Inline remediation suggestions
- 📈 Summary statistics and charts
JSON Report (CI/CD Ready)
{
"timestamp": "2026-06-05T10:30:00Z",
"total_findings": 15,
"severity_breakdown": {
"critical": 5,
"high": 8,
"medium": 2,
"low": 0
},
"findings": [...]
}
⚙️ Configuration
Create config/initializers/guarddog.rb:
# Enable only specific checkers
Rails.application.config.guarddog.enabled_checkers = %w[
sql_injection xss csrf mass_assignment secrets
ai_injection idor dos rate_limit
]
# Fail on severity level (for CI)
Rails.application.config.guarddog.fail_on_severity = :critical
# Strict mode (catch more issues, may have false positives)
Rails.application.config.guarddog.strict_mode = false
📖 Documentation
- README - Complete feature overview
- Security Coverage - Detailed breakdown of all 12 checkers
- Quick Start - Get running in 5 minutes
- Publishing Guide - GitHub + RubyGems setup
🔄 CI/CD Integration
GitHub Actions
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
if: always()
uses: actions/upload-artifact@v3
with:
name: guarddog-report
path: guarddog_report.*
GitLab CI
security_scan:
image: ruby:3.2
script:
- bundle install
- bundle exec rake guarddog:ci
artifacts:
paths:
- guarddog_report.*
when: always
🔐 Security Checkers Detail
1. SQL Injection
# ❌ DETECTED
User.where("id = #{params[:id]}")
User.find_by_sql("SELECT * FROM users WHERE id = #{id}")
# ✅ SAFE
User.where('id = ?', params[:id])
User.where(id: params[:id])
CWE: 89 | OWASP: A03:2021
2. XSS (Cross-Site Scripting)
<!-- ❌ DANGEROUS -->
<%= @user.bio %>
<!-- ✅ SAFE -->
<%= sanitize @user.bio %>
CWE: 79 | OWASP: A07:2021
3. CSRF (Cross-Site Request Forgery)
# ❌ CRITICAL (without documented reason)
skip_before_action :verify_authenticity_token
# ✅ DOCUMENTED
# CSRF disabled for API endpoints
skip_before_action :verify_authenticity_token, if: :json_request?
CWE: 352 | OWASP: A01:2021
4. Mass Assignment
# ❌ CRITICAL
params.permit!
# ✅ SAFE
params.require(:user).permit(:name, :email, :age)
CWE: 915 | OWASP: A01:2021
5. Hardcoded Secrets
# ❌ CRITICAL
API_KEY = "sk_live_abc123def456"
# ✅ SAFE
ENV['API_KEY']
Rails.application.credentials.api_key
CWE: 798 | OWASP: A02:2021
6. DoS/ReDoS
# ❌ HIGH RISK
User.all
/(a|a)*$/.match?('aaaa')
# ✅ SAFE
User.limit(100)
/^a+$/.match?('aaaa')
CWE: 400, 1333 | OWASP: A05:2021
7. IDOR
# ❌ CRITICAL
@post = Post.find(params[:id])
# ✅ SAFE
@post = current_user.posts.find(params[:id])
@post
CWE: 639 | OWASP: A01:2021
8. AI/LLM Prompt Injection
# ❌ CRITICAL
response = client..create(
messages: [{ role: "user", content: params[:question] }]
)
# ✅ SAFE
prompt = "Summarize: #{sanitize(params[:text]).first(500)}"
response = client..create(
messages: [{ role: "user", content: prompt }]
)
CWE: 94 | OWASP: A03:2025
🐕 Why "GuardDog"?
Like a good guard dog, Rails GuardDog protects your application:
- 🐾 Watches for intruders (security vulnerabilities)
- 🚨 Barks when danger is near (alerts on findings)
- 🛡️ Guards the perimeter (checks entire codebase)
- 👀 Never sleeps (always-on scanning)
- 🤝 Works alongside you (integrates with your workflow)
🤝 Contributing
Contributions welcome! Areas for enhancement:
- Additional security checkers
- Performance optimizations
- More language support
- Advanced AST analysis
- Machine learning pattern detection
GitHub Issues | GitHub Discussions
📄 License
MIT License - Free to use and modify. See LICENSE for details.
🔗 Links
- RubyGems: https://rubygems.org/gems/rails-guarddog
- GitHub: https://github.com/sghani001/rails-guarddog
- Issues: https://github.com/sghani001/rails-guarddog/issues
- Changelog: https://github.com/sghani001/rails-guarddog/releases
Beyond brakeman. Detect what others miss. 🐕🔒