Rails GuardDog 🐕

Gem Version Downloads GitHub Stars License: MIT Ruby Version Rails Version Issues Status

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 Gem Version
Total Downloads 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_to without 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 Assignmentpermit! 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


🔄 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])
authorize @post

CWE: 639 | OWASP: A01:2021

8. AI/LLM Prompt Injection

# ❌ CRITICAL
response = client.messages.create(
  messages: [{ role: "user", content: params[:question] }]
)

# ✅ SAFE
prompt = "Summarize: #{sanitize(params[:text]).first(500)}"
response = client.messages.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.



Beyond brakeman. Detect what others miss. 🐕🔒