Rails GuardDog: Advanced Security Scanner for Rails Applications

ruby dev.to

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:

  1. AI/LLM Integration - How do you prevent prompt injection when integrating with ChatGPT, Claude, or Anthropic?
  2. ReDoS Attacks - Catastrophic backtracking in regex can bring down your app
  3. Supply Chain Attacks - Typosquatted gems that look like popular libraries
  4. IDOR Gaps - Objects accessible without proper authorization checks
  5. 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

  1. SQL Injection - String interpolation in queries
  2. XSS - Unescaped output in views
  3. CSRF - Disabled protection verification
  4. Mass Assignment - permit! vulnerabilities (fixes Brakeman #1942, #1918)
  5. Open Redirect - User input in redirects
  6. Hardcoded Secrets - API keys, tokens, passwords (always-on, fixes #1989)
  7. DoS/ReDoS - Unbounded queries, dangerous regex patterns
  8. IDOR - Object access without authorization
  9. AI/LLM Prompt Injection - User input flowing to LLMs
  10. Rate Limiting - Missing rack-attack configuration
  11. Supply Chain - Typosquatted gems using Levenshtein distance
  12. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

  1. A developer passed user input directly to Claude without sanitization
  2. We found dangerous regex patterns that could cause ReDoS attacks
  3. A typosquatted gem almost made it into production
  4. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.*
Enter fullscreen mode Exit fullscreen mode

Get Started

Rails GuardDog is available now on RubyGems:

gem 'rails-guarddog'
Enter fullscreen mode Exit fullscreen mode

Next Steps

  1. Try it in your Rails app: gem 'rails-guarddog'
  2. Run: rake guarddog:scan
  3. Check the HTML report: rake guarddog:report
  4. Add to CI: rake guarddog:ci
  5. Share feedback: GitHub issues

Contributing

Found a bug? Have an idea? Contributions welcome!

Questions?

Drop a comment below or reach out on GitHub!


Rails GuardDog v0.1.0 is production-ready and available now. 🐕

Rails #Security #RubyGems #WebDevelopment #AppSecurity #OpenSource

Source: dev.to

arrow_back Back to Tutorials