rails-guarddog 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b5176cbe7acb78424e6f30a57cb8c203d5de27d9c2e12627034ee33a723c3095
4
- data.tar.gz: 22408c90ed568ef535fced6db89e92a96c7b79aec37cc81631abb7a0a5393498
3
+ metadata.gz: 469fc7ebf2cb0470aa7d3051c7428bd3572c46613f7b4e4579cd4dea51abebe3
4
+ data.tar.gz: 90d2fbd4f8a92486543db40c340d6639bffe9a360c75ad0a2ddc2a0d72b6d5b3
5
5
  SHA512:
6
- metadata.gz: fc28d9a40e236b423c809aaddefed91c6de16a6108563e1d47512f8d2d5ef91a0caac2e3113c240e6d55483b272c87603a8dfa190bcdb14213604166bc547eb4
7
- data.tar.gz: 1d0e968eaf094a70a7854dfe5223c048a02f445f475345b3d5edb0e7a12448c398c960d18b1a5f0d6fa9a9dbbd2f8a1813141739a74cf9a55fcb4281a1fea719
6
+ metadata.gz: c9b7bef99b68fa70ad3f6774f386ad627352a0dabc3c616cf748d7189686cd7898bf0967acbcf3e4b55f033d697a13c3e40a7d0ace48208a7020c71543371ffb
7
+ data.tar.gz: 1e658a6ef523c9ed570423bb369db75596e250332df8a0ff2c0e56df3a979fa23074edb031e2263b3df80b857b50e9a7bd804bfdeca6577c707fbceaef80629d
data/README.md CHANGED
@@ -1,314 +1,322 @@
1
- # Rails GuardDog 🐕
2
-
3
- [![Gem Version](https://img.shields.io/gem/v/rails-guarddog.svg)](https://rubygems.org/gems/rails-guarddog)
4
- [![Downloads](https://img.shields.io/gem/dt/rails-guarddog.svg)](https://rubygems.org/gems/rails-guarddog)
5
- [![GitHub Stars](https://img.shields.io/github/stars/sghani001/rails-guarddog.svg)](https://github.com/sghani001/rails-guarddog)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
- [![Ruby Version](https://img.shields.io/badge/ruby-%3E%3D3.0-red.svg)](https://www.ruby-lang.org/)
8
- [![Rails Version](https://img.shields.io/badge/rails-%3E%3D6.0-red.svg)](https://rubyonrails.org/)
9
- [![Issues](https://img.shields.io/github/issues/sghani001/rails-guarddog.svg)](https://github.com/sghani001/rails-guarddog/issues)
10
- ![Status](https://img.shields.io/badge/status-Production%20Ready-brightgreen.svg)
11
-
12
- **Production-grade security scanner for Rails applications.**
13
-
14
- Beyond Brakeman — detects AI injection, DoS patterns, supply chain attacks, GraphQL authorization gaps, and more.
15
-
16
- > **v0.1.8Now with enhanced AI injection detection, improved supply chain analysis, and 40% faster scanning.**
17
-
18
- ---
19
-
20
- ## ✨ Why Rails GuardDog?
21
-
22
- | Feature | Brakeman | bundler-audit | rack-attack | GuardDog |
23
- |---------|----------|---------------|-------------|----------|
24
- | SQL Injection | ✅ | - | - | ✅ Enhanced |
25
- | XSS Detection | ✅ | - | - | ✅ Extended |
26
- | CSRF Checks | ✅ | - | - | ✅ Full |
27
- | Mass Assignment | ✅ Partial | - | - | ✅ **Improved** |
28
- | Hardcoded Secrets | ⚠️ Optional | - | - | ✅ **Always-on** |
29
- | Open Redirect | ✅ | - | - | ✅ |
30
- | **DoS/ReDoS** | ❌ | - | - | ✅ **Enhanced** |
31
- | **IDOR** | ❌ | - | - | ✅ |
32
- | **AI Injection** | ❌ | - | - | ✅ **Enhanced** |
33
- | **Supply Chain** | ❌ | ⚠️ Limited | - | ✅ **Improved** |
34
- | **Rate Limiting** | ❌ | - | ⚠️ Config only | ✅ **Expanded** |
35
- | **GraphQL Auth** | ❌ | - | - | ✅ |
36
-
37
- ---
38
-
39
- ## 📊 By The Numbers
40
-
41
- | Metric | Value |
42
- |--------|-------|
43
- | **Latest Version** | [![Gem Version](https://img.shields.io/gem/v/rails-guarddog.svg)](https://rubygems.org/gems/rails-guarddog) |
44
- | **Total Downloads** | [![Downloads](https://img.shields.io/gem/dt/rails-guarddog.svg)](https://rubygems.org/gems/rails-guarddog) |
45
- | **Security Checkers** | 12 |
46
- | **Report Formats** | 3 (Console, HTML, JSON) |
47
- | **Core Dependencies** | 2 (parser, ast) |
48
- | **Performance** | 40% faster AST analysis |
49
- | **Memory** | 25% smaller footprint |
50
- | **License** | MIT |
51
-
52
- ---
53
-
54
- ## 🚀 Quick Start
55
-
56
- ### Installation
57
-
58
- Add to your Gemfile:
59
- ```ruby
60
- gem 'rails-guarddog'
61
- ```
62
-
63
- Then run:
64
- ```bash
65
- bundle install
66
- ```
67
-
68
- ### First Scan
69
-
70
- ```bash
71
- # See results in terminal
72
- rake guarddog:scan
73
-
74
- # Generate HTML + JSON reports
75
- rake guarddog:report
76
-
77
- # CI/CD integration (exits 1 if critical found)
78
- rake guarddog:ci
79
- ```
80
-
81
- That's it! Scan your entire Rails app for security vulnerabilities.
82
-
83
- ---
84
-
85
- ## 🔒 Security Checkers (12 Total)
86
-
87
- ### Authentication & Authorization
88
- - **IDOR Detection** — Object access without ownership verification
89
- - **GraphQL Authorization** — Missing field-level auth checks
90
- - **Open Redirect** — User input in `redirect_to` without validation
91
- - **Rate Limiting Audit** — Missing rack-attack configuration
92
-
93
- ### Injection Attacks
94
- - **SQL Injection** — String interpolation in queries
95
- - **XSS (Cross-Site Scripting)** — Unescaped user input in views
96
- - **AI/LLM Prompt Injection** — User input flowing directly to LLMs ⭐ ENHANCED in v0.1.8
97
-
98
- ### Data Protection
99
- - **CSRF Protection** — Disabled without documented reason
100
- - **Mass Assignment** — `permit!` vulnerabilities ⭐ IMPROVED in v0.1.8
101
- - **Hardcoded Secrets** — API keys, tokens, passwords in code (ALWAYS-ON, false-positive-safe)
102
-
103
- ### Resource Management
104
- - **DoS/ReDoS** — Unbounded queries, dangerous regex patterns ⭐ ENHANCED in v0.1.8
105
- - **Supply Chain** — Typosquatted gems using Levenshtein distance ⭐ IMPROVED in v0.1.8
106
-
107
- > **False-positive protection (v0.1.10 - v0.1.13)**
108
- > - **Secrets**: Patterns use word boundaries — `no_token:` or `reset_password_instructions:` in locale
109
- > files will **not** trigger the secrets checker.
110
- > - **Secrets**: Secret values must be space-free (`[^\s'"]{6,}`) — human-readable sentences like
111
- > `"You can't access this page..."` are never flagged.
112
- > - **Secrets**: `config/locales/` files are skipped entirely — i18n translations are not credentials.
113
- > - **Secrets**: `spec/` and `test/` trees suppress the secrets checker by default (configurable via
114
- > `ignored_checks`).
115
- > - **DoS**: Smart multiline `.limit()` check detection (v0.1.12) — lookahead up to 3 lines handles chained
116
- > `.limit()` calls on subsequent lines or reassignment to the same variable, e.g. `things = Thing.all; things = things.limit(100)` or `.limit(...)` on the next line.
117
- > - **Ignore File**: Support for `.guarddogignore` (v0.1.13) — allows excluding complete files/directories or ignoring specific checkers for specific files/directories.
118
-
119
-
120
- ## 📊 Example Output
121
-
122
- ### Console Report
123
- ```
124
- ============================================================
125
- Rails GuardDog Security Report v0.1.13
126
- ============================================================
127
-
128
- [CRITICAL] (5 findings)
129
- Mass Assignment permit! allows ALL parameters
130
- app/controllers/users_controller.rb:15
131
- Fix: Use permit(:name, :email, :age) for specific fields
132
-
133
- AI Injection — User input in LLM prompt
134
- app/services/chat_service.rb:42
135
- Fix: Sanitize: prompt = 'Template: ' + sanitize(params[:text])
136
-
137
- Hardcoded Secret — API Key detected
138
- config/initializers/api.rb:3
139
- Fix: Move to Rails.application.credentials
140
-
141
- [HIGH] (8 findings)
142
- DoS: Unbounded query without limit
143
- app/controllers/posts_controller.rb:5
144
- Fix: Add .limit(100) or use pagination
145
-
146
- ============================================================
147
- Total findings: 15 | Critical: 5 | High: 8
148
- ============================================================
149
- ```
150
-
151
- ### HTML Report
152
- - 📊 Interactive dashboard with severity filtering
153
- - 🎨 Color-coded findings
154
- - 💡 Inline remediation suggestions
155
- - 📈 Summary statistics
156
- - 🌙 Dark mode support
157
- - 📄 PDF export (beta)
158
-
159
- ### JSON Report (CI/CD Ready)
160
- ```json
161
- {
162
- "timestamp": "2026-06-06T04:00:00Z",
163
- "total_findings": 15,
164
- "severity_breakdown": {
165
- "critical": 5,
166
- "high": 8
167
- }
168
- }
169
- ```
170
-
171
- ---
172
-
173
- ## ⚙️ Configuration
174
-
175
- Create `config/initializers/guarddog.rb`:
176
-
177
- ```ruby
178
- Rails.application.config.after_initialize do
179
- # --- Option A: Enable only specific checkers ---
180
- Rails.application.config.guarddog.enabled_checkers = %w[
181
- sql_injection xss csrf mass_assignment secrets
182
- ai_injection idor dos rate_limit supply_chain
183
- ]
184
-
185
- # --- Option B: Disable only specific checkers (keep everything else) ---
186
- # Easier when you want "all but a couple". Takes priority over enabled_checkers.
187
- Rails.application.config.guarddog.disabled_checkers = %w[dos rate_limit]
188
-
189
- # Directories to skip entirely (all checks silenced).
190
- # Default: %w[vendor node_modules]
191
- Rails.application.config.guarddog.excluded_paths = %w[vendor node_modules]
192
-
193
- # Suppress specific checkers for files under certain path substrings.
194
- # Keys are path fragments; values are arrays of checker names.
195
- # Default: { "spec" => %w[secrets], "test" => %w[secrets] }
196
- Rails.application.config.guarddog.ignored_checks = {
197
- "spec" => %w[secrets], # no secrets alerts in spec/
198
- "test" => %w[secrets], # no secrets alerts in test/
199
- "fixtures" => %w[secrets idor] # custom: also skip idor in fixtures
200
- }
201
-
202
- # Fail on severity level (for CI)
203
- Rails.application.config.guarddog.fail_on_severity = :critical
204
-
205
- # Strict mode (catch more issues, may have false positives)
206
- Rails.application.config.guarddog.strict_mode = false
207
- end
208
- ```
209
-
210
- ### Disabling specific checkers
211
-
212
- If you want to keep all checkers **except a couple**, use `disabled_checkers`
213
- instead of maintaining a long `enabled_checkers` list:
214
-
215
- ```ruby
216
- # All 12 checkers run, except dos and rate_limit
217
- Rails.application.config.guarddog.disabled_checkers = %w[dos rate_limit]
218
- ```
219
-
220
- This is the recommended approach when you hit false positives in one checker
221
- but still want full coverage from all others.
222
-
223
- ### Suppressing checks per directory
224
-
225
- GuardDog already silences `secrets` in `spec/` and `test/` by default. To add
226
- more suppressions or override the defaults, set `ignored_checks` in your
227
- initializer (see example above).
228
-
229
- ### Ignoring findings with `.guarddogignore`
230
-
231
- You can add a `.guarddogignore` file in the root of your Rails project to exclude entire files/directories or ignore specific checkers for specific files.
232
-
233
- - To exclude a file or directory completely (silence all checkers), list the path:
234
- ```
235
- db/seeds.rb
236
- vendor/
237
- ```
238
-
239
- - To skip only specific checkers for certain files or directories, separate the path and the comma-separated list of checkers with a `:`:
240
- ```
241
- db/seeds.rb: secrets
242
- app/controllers/admin/*: sql_injection, csrf
243
- ```
244
-
245
- ---
246
-
247
-
248
- ## 🔄 CI/CD Integration
249
-
250
- ### GitHub Actions
251
- ```yaml
252
- name: Security Scan
253
- on: [push, pull_request]
254
- jobs:
255
- guarddog:
256
- runs-on: ubuntu-latest
257
- steps:
258
- - uses: actions/checkout@v3
259
- - uses: ruby/setup-ruby@v1
260
- with:
261
- ruby-version: '3.2'
262
- bundler-cache: true
263
- - name: Run GuardDog
264
- run: bundle exec rake guarddog:ci
265
- ```
266
-
267
- ---
268
-
269
- ## 📈 What's New in v0.1.8
270
-
271
- Enhanced AI/LLM Injection Detection
272
- Improved Supply Chain Analysis
273
- Expanded DoS/ReDoS Patterns
274
- ✨ 40% Faster AST Analysis
275
- ✨ Better HTML Report
276
- 🎯 5 Critical Bug Fixes
277
-
278
- ---
279
-
280
- ## 🐕 Why "GuardDog"?
281
-
282
- Like a good guard dog, Rails GuardDog protects your application:
283
- - 🐾 Watches for intruders (security vulnerabilities)
284
- - 🚨 Barks when danger is near (alerts on findings)
285
- - 🛡️ Guards the perimeter (checks entire codebase)
286
- - 👀 Never sleeps (always-on scanning)
287
- - 🤝 Works alongside you (integrates with your workflow)
288
-
289
- ---
290
-
291
- ## 🤝 Contributing
292
-
293
- Contributions welcome! [GitHub Issues](https://github.com/sghani001/rails-guarddog/issues) | [GitHub Discussions](https://github.com/sghani001/rails-guarddog/discussions)
294
-
295
- ---
296
-
297
- ## 📄 License
298
-
299
- MIT License - Free to use and modify.
300
-
301
- ---
302
-
303
- ## 🔗 Links
304
-
305
- - **RubyGems:** https://rubygems.org/gems/rails-guarddog
306
- - **GitHub:** https://github.com/sghani001/rails-guarddog
307
- - **Issues:** https://github.com/sghani001/rails-guarddog/issues
308
- - **Releases:** https://github.com/sghani001/rails-guarddog/releases
309
-
310
- ---
311
-
312
- **Rails GuardDog v0.1.13 — Production Ready**
313
-
314
- *Beyond brakeman. Detect what others miss.* 🐕🔒
1
+ # Rails GuardDog 🐕
2
+
3
+ [![Gem Version](https://img.shields.io/gem/v/rails-guarddog.svg)](https://rubygems.org/gems/rails-guarddog)
4
+ [![Downloads](https://img.shields.io/gem/dt/rails-guarddog.svg)](https://rubygems.org/gems/rails-guarddog)
5
+ [![GitHub Stars](https://img.shields.io/github/stars/dev-syedghani/rails-guarddog.svg)](https://github.com/dev-syedghani/rails-guarddog)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+ [![Ruby Version](https://img.shields.io/badge/ruby-%3E%3D3.0-red.svg)](https://www.ruby-lang.org/)
8
+ [![Rails Version](https://img.shields.io/badge/rails-%3E%3D6.0-red.svg)](https://rubyonrails.org/)
9
+ [![Issues](https://img.shields.io/github/issues/dev-syedghani/rails-guarddog.svg)](https://github.com/dev-syedghani/rails-guarddog/issues)
10
+ ![Status](https://img.shields.io/badge/status-Production%20Ready-brightgreen.svg)
11
+
12
+ **Production-grade security scanner for Rails applications.**
13
+
14
+ Beyond Brakeman — detects AI injection, DoS patterns, supply chain attacks, GraphQL authorization gaps, and more.
15
+
16
+ > **v0.1.15SQL Injection checker rewritten to parse `.where`/`.find_by_sql` arguments directly (instead of a single-line regex), fixing false positives on multi-line calls and safe interpolation in bind-value arguments.**
17
+
18
+ ---
19
+
20
+ ## ✨ Why Rails GuardDog?
21
+
22
+ | Feature | Brakeman | bundler-audit | rack-attack | GuardDog |
23
+ |---------|----------|---------------|-------------|----------|
24
+ | SQL Injection | ✅ | - | - | ✅ Enhanced |
25
+ | XSS Detection | ✅ | - | - | ✅ Extended |
26
+ | CSRF Checks | ✅ | - | - | ✅ Full |
27
+ | Mass Assignment | ✅ Partial | - | - | ✅ **Improved** |
28
+ | Hardcoded Secrets | ⚠️ Optional | - | - | ✅ **Always-on** |
29
+ | Open Redirect | ✅ | - | - | ✅ |
30
+ | **DoS/ReDoS** | ❌ | - | - | ✅ **Enhanced** |
31
+ | **IDOR** | ❌ | - | - | ✅ |
32
+ | **AI Injection** | ❌ | - | - | ✅ **Enhanced** |
33
+ | **Supply Chain** | ❌ | ⚠️ Limited | - | ✅ **Improved** |
34
+ | **Rate Limiting** | ❌ | - | ⚠️ Config only | ✅ **Expanded** |
35
+ | **GraphQL Auth** | ❌ | - | - | ✅ |
36
+
37
+ ---
38
+
39
+ ## 📊 By The Numbers
40
+
41
+ | Metric | Value |
42
+ |--------|-------|
43
+ | **Latest Version** | [![Gem Version](https://img.shields.io/gem/v/rails-guarddog.svg)](https://rubygems.org/gems/rails-guarddog) |
44
+ | **Total Downloads** | [![Downloads](https://img.shields.io/gem/dt/rails-guarddog.svg)](https://rubygems.org/gems/rails-guarddog) |
45
+ | **Security Checkers** | 12 |
46
+ | **Report Formats** | 3 (Console, HTML, JSON) |
47
+ | **Core Dependencies** | 2 (parser, ast) |
48
+ | **Performance** | 40% faster AST analysis |
49
+ | **Memory** | 25% smaller footprint |
50
+ | **License** | MIT |
51
+
52
+ ---
53
+
54
+ ## 🚀 Quick Start
55
+
56
+ ### Installation
57
+
58
+ Add to your Gemfile:
59
+ ```ruby
60
+ gem 'rails-guarddog'
61
+ ```
62
+
63
+ Then run:
64
+ ```bash
65
+ bundle install
66
+ ```
67
+
68
+ ### First Scan
69
+
70
+ ```bash
71
+ # See results in terminal
72
+ rake guarddog:scan
73
+
74
+ # Generate HTML + JSON reports
75
+ rake guarddog:report
76
+
77
+ # CI/CD integration (exits 1 if critical found)
78
+ rake guarddog:ci
79
+ ```
80
+
81
+ That's it! Scan your entire Rails app for security vulnerabilities.
82
+
83
+ ---
84
+
85
+ ## 🔒 Security Checkers (12 Total)
86
+
87
+ ### Authentication & Authorization
88
+ - **IDOR Detection** — Object access without ownership verification
89
+ - **GraphQL Authorization** — Missing field-level auth checks
90
+ - **Open Redirect** — User input in `redirect_to` without validation
91
+ - **Rate Limiting Audit** — Missing rack-attack configuration
92
+
93
+ ### Injection Attacks
94
+ - **SQL Injection** — String interpolation in queries
95
+ - **XSS (Cross-Site Scripting)** — Unescaped user input in views
96
+ - **AI/LLM Prompt Injection** — User input flowing directly to LLMs ⭐ ENHANCED in v0.1.8
97
+
98
+ ### Data Protection
99
+ - **CSRF Protection** — Disabled without documented reason
100
+ - **Mass Assignment** — `permit!` vulnerabilities ⭐ IMPROVED in v0.1.8
101
+ - **Hardcoded Secrets** — API keys, tokens, passwords in code (ALWAYS-ON, false-positive-safe)
102
+
103
+ ### Resource Management
104
+ - **DoS/ReDoS** — Unbounded queries, dangerous regex patterns ⭐ ENHANCED in v0.1.8
105
+ - **Supply Chain** — Typosquatted gems using Levenshtein distance ⭐ IMPROVED in v0.1.8
106
+
107
+ > **False-positive protection (v0.1.10 - v0.1.15)**
108
+ > - **Secrets**: Patterns use word boundaries — `no_token:` or `reset_password_instructions:` in locale
109
+ > files will **not** trigger the secrets checker.
110
+ > - **Secrets**: Secret values must be space-free (`[^\s'"]{6,}`) — human-readable sentences like
111
+ > `"You can't access this page..."` are never flagged.
112
+ > - **Secrets**: `config/locales/` files are skipped entirely — i18n translations are not credentials.
113
+ > - **Secrets**: `spec/` and `test/` trees suppress the secrets checker by default (configurable via
114
+ > `ignored_checks`).
115
+ > - **DoS**: Smart multiline `.limit()` check detection (v0.1.12) — lookahead up to 3 lines handles chained
116
+ > `.limit()` calls on subsequent lines or reassignment to the same variable, e.g. `things = Thing.all; things = things.limit(100)` or `.limit(...)` on the next line.
117
+ > - **Ignore File**: Support for `.guarddogignore` (v0.1.13) — allows excluding complete files/directories or ignoring specific checkers for specific files/directories.
118
+ > - **SQL Injection**: Precise argument-boundary matching (v0.1.14) — prevents false positives when string interpolation is used safely in query bind arguments (e.g. `where("column ILIKE ?", "#{value}%")`).
119
+ > - **DoS**: Pagy pagination support (v0.1.14) — query calls inside `pagy(...)` or `pagy_countless(...)` helpers are recognized as paginated and are not flagged as unbounded.
120
+ > - **SQL Injection**: Argument-aware parsing (v0.1.15) — `.where`/`.find_by_sql` calls are now parsed by walking the actual argument list (tracking quotes/parens/interpolation) instead of a single-line regex, fixing false positives on multi-line calls, e.g.:
121
+ > ```ruby
122
+ > base = base.where(
123
+ > "street_number ILIKE ?",
124
+ > "#{Address.sanitize_sql_like(number)}%"
125
+ > )
126
+ > ```
127
+
128
+
129
+ ## 📊 Example Output
130
+
131
+ ### Console Report
132
+ ```
133
+ ============================================================
134
+ Rails GuardDog Security Report v0.1.15
135
+ ============================================================
136
+
137
+ [CRITICAL] (5 findings)
138
+ Mass Assignment — permit! allows ALL parameters
139
+ app/controllers/users_controller.rb:15
140
+ Fix: Use permit(:name, :email, :age) for specific fields
141
+
142
+ AI Injection User input in LLM prompt
143
+ app/services/chat_service.rb:42
144
+ Fix: Sanitize: prompt = 'Template: ' + sanitize(params[:text])
145
+
146
+ Hardcoded Secret — API Key detected
147
+ config/initializers/api.rb:3
148
+ Fix: Move to Rails.application.credentials
149
+
150
+ [HIGH] (8 findings)
151
+ DoS: Unbounded query without limit
152
+ app/controllers/posts_controller.rb:5
153
+ Fix: Add .limit(100) or use pagination
154
+
155
+ ============================================================
156
+ Total findings: 15 | Critical: 5 | High: 8
157
+ ============================================================
158
+ ```
159
+
160
+ ### HTML Report
161
+ - 📊 Interactive dashboard with severity filtering
162
+ - 🎨 Color-coded findings
163
+ - 💡 Inline remediation suggestions
164
+ - 📈 Summary statistics
165
+ - 🌙 Dark mode support
166
+ - 📄 PDF export (beta)
167
+
168
+ ### JSON Report (CI/CD Ready)
169
+ ```json
170
+ {
171
+ "timestamp": "2026-06-06T04:00:00Z",
172
+ "total_findings": 15,
173
+ "severity_breakdown": {
174
+ "critical": 5,
175
+ "high": 8
176
+ }
177
+ }
178
+ ```
179
+
180
+ ---
181
+
182
+ ## ⚙️ Configuration
183
+
184
+ Create `config/initializers/guarddog.rb`:
185
+
186
+ ```ruby
187
+ Rails.application.config.after_initialize do
188
+ # --- Option A: Enable only specific checkers ---
189
+ Rails.application.config.guarddog.enabled_checkers = %w[
190
+ sql_injection xss csrf mass_assignment secrets
191
+ ai_injection idor dos rate_limit supply_chain
192
+ ]
193
+
194
+ # --- Option B: Disable only specific checkers (keep everything else) ---
195
+ # Easier when you want "all but a couple". Takes priority over enabled_checkers.
196
+ Rails.application.config.guarddog.disabled_checkers = %w[dos rate_limit]
197
+
198
+ # Directories to skip entirely (all checks silenced).
199
+ # Default: %w[vendor node_modules]
200
+ Rails.application.config.guarddog.excluded_paths = %w[vendor node_modules]
201
+
202
+ # Suppress specific checkers for files under certain path substrings.
203
+ # Keys are path fragments; values are arrays of checker names.
204
+ # Default: { "spec" => %w[secrets], "test" => %w[secrets] }
205
+ Rails.application.config.guarddog.ignored_checks = {
206
+ "spec" => %w[secrets], # no secrets alerts in spec/
207
+ "test" => %w[secrets], # no secrets alerts in test/
208
+ "fixtures" => %w[secrets idor] # custom: also skip idor in fixtures
209
+ }
210
+
211
+ # Fail on severity level (for CI)
212
+ Rails.application.config.guarddog.fail_on_severity = :critical
213
+
214
+ # Strict mode (catch more issues, may have false positives)
215
+ Rails.application.config.guarddog.strict_mode = false
216
+ end
217
+ ```
218
+
219
+ ### Disabling specific checkers
220
+
221
+ If you want to keep all checkers **except a couple**, use `disabled_checkers`
222
+ instead of maintaining a long `enabled_checkers` list:
223
+
224
+ ```ruby
225
+ # All 12 checkers run, except dos and rate_limit
226
+ Rails.application.config.guarddog.disabled_checkers = %w[dos rate_limit]
227
+ ```
228
+
229
+ This is the recommended approach when you hit false positives in one checker
230
+ but still want full coverage from all others.
231
+
232
+ ### Suppressing checks per directory
233
+
234
+ GuardDog already silences `secrets` in `spec/` and `test/` by default. To add
235
+ more suppressions or override the defaults, set `ignored_checks` in your
236
+ initializer (see example above).
237
+
238
+ ### Ignoring findings with `.guarddogignore`
239
+
240
+ You can add a `.guarddogignore` file in the root of your Rails project to exclude entire files/directories or ignore specific checkers for specific files.
241
+
242
+ - To exclude a file or directory completely (silence all checkers), list the path:
243
+ ```
244
+ db/seeds.rb
245
+ vendor/
246
+ ```
247
+
248
+ - To skip only specific checkers for certain files or directories, separate the path and the comma-separated list of checkers with a `:`:
249
+ ```
250
+ db/seeds.rb: secrets
251
+ app/controllers/admin/*: sql_injection, csrf
252
+ ```
253
+
254
+ ---
255
+
256
+
257
+ ## 🔄 CI/CD Integration
258
+
259
+ ### GitHub Actions
260
+ ```yaml
261
+ name: Security Scan
262
+ on: [push, pull_request]
263
+ jobs:
264
+ guarddog:
265
+ runs-on: ubuntu-latest
266
+ steps:
267
+ - uses: actions/checkout@v3
268
+ - uses: ruby/setup-ruby@v1
269
+ with:
270
+ ruby-version: '3.2'
271
+ bundler-cache: true
272
+ - name: Run GuardDog
273
+ run: bundle exec rake guarddog:ci
274
+ ```
275
+
276
+ ---
277
+
278
+ ## 📈 What's New in v0.1.15
279
+
280
+ **SQL Injection checker rewrite**: `.where`/`.find_by_sql` calls are parsed by walking the actual argument list (tracking quotes, parens, and interpolation) instead of a single-line regex, fixing false positives on multi-line calls.
281
+ ✨ **Ignore File support (`.guarddogignore`)**: Exclude entire files/directories or ignore specific checkers for specific paths.
282
+ **Custom checker exclusion (`disabled_checkers`)**: Keep all checkers active *except* a few specified ones without maintaining a long enabled list.
283
+ ✨ **SQL Injection & DoS False-Positive Protection**: String interpolation inside query bind arguments is now ignored; Pagy paginated queries are recognized and bypassed.
284
+ **Improved Secrets matching**: Avoid matching i18n/locale files, dummy variables (like `no_token:`), or full human-readable sentences.
285
+
286
+ ---
287
+
288
+ ## 🐕 Why "GuardDog"?
289
+
290
+ Like a good guard dog, Rails GuardDog protects your application:
291
+ - 🐾 Watches for intruders (security vulnerabilities)
292
+ - 🚨 Barks when danger is near (alerts on findings)
293
+ - 🛡️ Guards the perimeter (checks entire codebase)
294
+ - 👀 Never sleeps (always-on scanning)
295
+ - 🤝 Works alongside you (integrates with your workflow)
296
+
297
+ ---
298
+
299
+ ## 🤝 Contributing
300
+
301
+ Contributions welcome! [GitHub Issues](https://github.com/dev-syedghani/rails-guarddog/issues) | [GitHub Discussions](https://github.com/dev-syedghani/rails-guarddog/discussions)
302
+
303
+ ---
304
+
305
+ ## 📄 License
306
+
307
+ MIT License - Free to use and modify.
308
+
309
+ ---
310
+
311
+ ## 🔗 Links
312
+
313
+ - **RubyGems:** https://rubygems.org/gems/rails-guarddog
314
+ - **GitHub:** https://github.com/dev-syedghani/rails-guarddog
315
+ - **Issues:** https://github.com/dev-syedghani/rails-guarddog/issues
316
+ - **Releases:** https://github.com/dev-syedghani/rails-guarddog/releases
317
+
318
+ ---
319
+
320
+ **Rails GuardDog v0.1.15 — Production Ready**
321
+
322
+ *Beyond brakeman. Detect what others miss.* 🐕🔒