mahdisphp / laravel-hack-auditor
AI-powered security auditor & CTF generator for Laravel. Watch AI hack your app in 15 seconds.
Package info
github.com/mahdi-salmanzade/laravel-hack-auditor
pkg:composer/mahdisphp/laravel-hack-auditor
Requires
- php: ^8.3
- illuminate/console: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- laravel/ai: ^0.3|^1.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^10.0
- pestphp/pest: ^3.0|^4.0
README
Watch AI hack your Laravel app in 15 seconds.
Watch AI literally hack a vulnerable Laravel controller in front of your eyes — no setup, no API key.
composer require mahdisphp/laravel-hack-auditor php artisan hack:demo
That's it. Two commands. Watch 12 vulnerabilities get ripped out of a controller in your terminal.
Six commands. That's the whole package.
php artisan hack:demo # See it in action (no API key) php artisan hack:scan # Scan YOUR app with AI php artisan hack:scan --diff --html # Scan only changed files, export HTML report php artisan hack:ctf sql_injection # Turn vulns into CTF challenges php artisan hack:report --latest # Generate HTML report from saved scan php artisan hack:help # Full command reference php artisan hack:usage # Token usage & cost stats
hack:scan finds what PHPStan and Snyk can't:
- "This endpoint fetches a user by ID but never checks ownership" (IDOR)
- "Admin check reads
is_adminfrom the request, not the session" (Auth bypass) - "Login route has no throttle middleware" (Brute-forceable)
- "Any authenticated user can set their own plan to 'pro' without payment" (Auth bypass)
12 vulnerability types. OWASP Top 10 mapped. Every finding has file, line, explanation, and a copy-paste fix.
Low false-positive rate
v1.5 introduces taint analysis — the AI must trace every input-dependent finding as SOURCE → TRANSFORMS → SINK before reporting it. The parser then programmatically verifies the trace: if the source is config() not $request->input(), auto-drop. If an (int) cast or $request->validated() breaks the chain, auto-drop. Zero extra API calls.
On top of that, v1.4's context-aware scanning reads your actual Laravel architecture — route middleware stacks, FormRequest authorize() methods, Eloquent $fillable/$hidden, policies, global scopes — and feeds it all to the AI before analysis. Framework-aware allowlists recognize $this->authorize(), Gate::define(), $request->validated(), and other Laravel conventions that eliminate entire classes of false positives.
Tested on production Laravel apps with 15-42 controllers and a deliberately vulnerable test app (100% true positive rate, 0 false positives).
Multi-pass verification (v1.6)
Pass --verify to have the AI attempt a concrete exploit for every HIGH or CRITICAL finding. Findings the model can exploit retain their severity and ship with a copy-paste exploit payload (exploit_proof). Findings it cannot exploit are downgraded one tier (Critical→High, High→Medium) with the original severity preserved in original_severity for audit trail — a placeholder or hedging response is treated as no-exploit.
php artisan hack:scan --verify # → Verification 8/8 HIGH+ findings had working exploits (0 downgraded) # Verification tokens: 15,288 input + 1,702 output = 16,990 total
⚠️
--verifyapproximately doubles API cost on scans with many HIGH+ findings. Recommended for pre-release audits, not every CI run. Enable by default viaHACK_AUDITOR_VERIFY=true.
Technical failures (AI timeouts, malformed responses) leave the finding untouched rather than downgrading on noise. The JSON output gains a verification sub-object with verified/downgraded counts and a separate token bucket so pass-1 and pass-2 cost are distinguishable.
Token usage & cost tracking
Every scan shows token consumption and estimated cost. Auto-detects your AI provider's pricing from a built-in registry of 30+ models (Anthropic, OpenAI, Gemini, xAI, Ollama). Budget your scans with --limit.
Token Usage ...... 97,188 prompt + 3,080 completion = 100,268 total
AI Requests ...... 7
Estimated Cost ... $0.5629
Model ............ claude-opus-4-6 (anthropic)
Quick setup (2 minutes)
php artisan install:ai # Install Laravel AI
Add one API key to .env:
ANTHROPIC_API_KEY=sk-ant-your-key-here # or OPENAI_API_KEY, or GEMINI_API_KEY
Scan:
php artisan hack:scan
Done. The package uses whatever provider you configured in Laravel AI. Optionally override just for this package:
HACK_AUDITOR_AI_PROVIDER=anthropic HACK_AUDITOR_AI_MODEL=claude-opus-4-6
All scan flags
| Flag | What it does |
|---|---|
--path=app/Http/Controllers |
Scan specific directory or file |
--severity=High |
Filter to High+ only |
--fix |
Include fix suggestions |
--json |
JSON output for CI/CD |
--html |
Generate HTML report |
--save |
Save results to JSON file |
--force |
Skip confirmation prompt |
--detailed |
Full descriptions in table |
--diff |
Only scan git-changed files (great for CI) |
--base=develop |
Base branch for --diff |
--limit=50000 |
Cap token budget for the scan |
--baseline |
Apply baseline to suppress known findings (auto-applied if file exists) |
--update-baseline |
Save current findings as baseline |
--no-baseline |
Ignore baseline file |
Report flags
| Flag | What it does |
|---|---|
--latest |
Generate report from the most recent saved scan |
--id=ULID |
Generate report from a specific scan ID |
--output=path |
Custom output file path |
Usage flags
| Flag | What it does |
|---|---|
--days=30 |
Show usage from the last N days (default: 30) |
--json |
Output as JSON |
--clear |
Clear the usage log |
Generate CTF challenges from real vulns
Train your team by turning actual findings into Capture The Flag exercises:
php artisan hack:ctf sql_injection # By type php artisan hack:ctf --from-scan # From latest scan results php artisan hack:ctf --all # Generate for every finding
Each challenge outputs a ready-to-run directory: README, vulnerable code, solution, flag file, and docker-compose.
HTML reports, git-aware scanning, baselines
php artisan hack:scan --html # Beautiful dark-themed HTML report php artisan hack:scan --diff # Only scan files changed in your branch php artisan hack:scan --update-baseline # Accept current findings as known php artisan hack:report --latest # Regenerate report from saved scan
The HTML report is a single self-contained file — dark theme, animated score ring, collapsible cards, copy-paste code blocks, token usage breakdown. Professional enough to attach to a security audit.
--diff scans only what your PR touches. --update-baseline lets teams acknowledge known risks so CI doesn't fail on accepted findings.
Use it in code
use Mahdi\HackAuditor\Facades\HackAuditor; use Mahdi\HackAuditor\Support\UsageTracker; $report = HackAuditor::scan(); if ($report->hasCritical()) { // Block deployment, alert Slack, panic, etc. } echo $report->overallScore; // 0-100 echo $report->criticalCount(); // int echo $report->getUsageTracker()?->totalTokens(); // tokens used echo $report->getUsageTracker()?->estimateCost(); // estimated $$$ // Budget-capped scan $tracker = new UsageTracker(tokenLimit: 50_000); $report = HackAuditor::scan(tracker: $tracker); // Scan history $history = HackAuditor::history(); $latest = $history->latest(); // array or null $all = $history->recent(10); // last 10 scans
CI/CD pipeline example
# .github/workflows/security.yml name: Security Audit on: [push, pull_request] jobs: hack-audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version: '8.3' - run: composer install --no-interaction - run: php artisan hack:scan --json --severity=High --force env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
All configuration options
php artisan vendor:publish --tag=hack-auditor-config
| Option | Default | Description |
|---|---|---|
ai.provider |
null |
AI provider override |
ai.model |
null |
Model override |
ai.temperature |
0.3 |
Lower = more deterministic |
ai.max_tokens |
4096 |
Max tokens per AI response |
ai.timeout |
120 |
HTTP timeout in seconds |
scan.paths |
Controllers, Models, Requests, Middleware, routes | What to scan |
scan.exclude |
*/vendor/*, */node_modules/*, */tests/* |
Excluded paths |
scan.file_extensions |
['.php'] |
File extensions to scan |
scan.max_file_size_kb |
500 |
Skip files larger than this |
scan.chunk_size |
10 |
Files per AI request |
scan.confirm_above_files |
20 |
Prompt before large scans |
scan.sensitive_patterns |
.env*, *.key, *.pem, storage/logs/* |
Always excluded |
scan.diff_base_branch |
null |
Base branch for --diff (auto-detects main/master) |
scan.baseline_path |
base_path('hack-auditor-baseline.json') |
Path to baseline JSON file |
context.enabled |
true |
Context-aware scanning (routes, middleware, policies, models) |
context.max_context_tokens |
8000 |
Token budget for context |
context.include_routes |
true |
Include route info in context |
context.include_middleware |
true |
Include middleware info in context |
context.include_policies |
true |
Include policy info in context |
context.include_form_requests |
true |
Include form request info in context |
context.include_models |
true |
Include model info in context |
context.extra_context_paths |
[] |
Additional paths to include in context |
severity.minimum_report |
'Low' |
Minimum severity to include in reports |
ctf.output_path |
hack-auditor/ctf |
CTF output directory |
report.output_path |
hack-auditor/reports |
HTML report output directory |
share.default_hashtags |
['#LaravelSecurity', '#HackAuditor', '#CTF'] |
Hashtags for sharing |
share.ai_tweets |
true |
AI-generated share text |
usage.default_limit |
0 |
Default --limit value (0 = unlimited) |
usage.cost_per_1m_input |
3.00 |
Cost per 1M input tokens |
usage.cost_per_1m_output |
15.00 |
Cost per 1M output tokens |
usage.show_usage |
true |
Show token usage after scan |
usage.log_enabled |
true |
Auto-log usage to storage/hack-auditor/usage.json |
Zero database dependencies. All data stored as JSON files in storage/hack-auditor/.
Security
This package sends source code to AI providers. Files matching .env*, *.key, *.pem, and storage/logs/* are always excluded. Review your provider's data retention policies.
Found a vulnerability in this package? Email mahdi@mindzone.tech.
Contributing
PRs welcome. Run composer test and vendor/bin/pint before submitting.
License
MIT — LICENSE
If this saved you from getting hacked, star the repo.

