Point it at a Laravel project and it finds broken access control (IDOR) — the bug class scanners miss. It never edits your code.
Scanners follow where untrusted input goes. They can't tell you whether Invoice::find($id) should have been limited to the logged-in user — that's about intent, and it's exactly the bug behind IDOR / broken access control (BOLA), #1 in the OWASP API Security Top 10. This skill fills that gap.
can: / FormRequest) → owner check → API output.update(Post $post) loads any record by id but never checks who owns it. The missing authorize() or owner check is the hole.php artisan route:list --json entry and a controller file:line. No proof, no finding.php artisan route:list --json), then hands you findings and fix ideas. It never edits your routes, controllers, policies, or code — you apply every fix yourself.
A real run, shortened. The route list and cited lines are hard facts; whether a model is "owned" or a field is sensitive is the skill's call — shown as an assumption for you to confirm.
## Summary 18 routes — 🔴 3 exposed 🟡 5 review 🔵 2 hardening ✅ 8 covered ## Coverage map DELETE /api/invoices/{invoice} auth ✓ authz ✗ scoped ✗ policy ✓ 🔴 exposed PUT /api/profile auth ✓ authz ✗ scoped n/a 🔴 authz off GET /api/orders/{order} auth ✓ authz ✓ scoped ✓ policy ✓ ✅ covered ## 🔴 Verify & fix now DELETE /api/invoices/{invoice} → InvoiceController@destroy:88 → implicit binding resolves ANY invoice; no authorize(), no owner scope → IDOR → Invoice is owned (invoices.user_id, User::invoices()) [High] → fix: $this->authorize('delete', $invoice) (InvoicePolicy::delete is missing) ## 🟡 Review — needs your judgment GET /api/invoices/{invoice} → show() returns model, no authorize('view') [Medium] → confirm: owned vs. team-shared → add authorize() or scope to the team
Clear holes — no login/permission/owner check on owned data. Confirm with the cited line, add the check, add a test.
Likely IDOR or data leak — depends on who owns the model or whether a field is sensitive. Decide, then add the check.
Extra safety — missing policy, owner keys open to mass-assignment. Tidy when convenient.
| Requirement | Why |
|---|---|
A Laravel project (artisan present) | the entry point; without it the skill stops |
The app boots enough to run php artisan route:list | the ground-truth route inventory |
Readable app/, routes/, app/Policies/ | to walk the authorization chain |
If the app can't boot, the skill reads routes/*.php instead and tells you the list is best-effort (lower confidence).
No marketplace or full library needed — drop this one folder into your project's .claude/skills/:
# grab just this skill (per-project) npx degit ArtemProshkovskiy/laravel-maintenance-skills/skills/laravel-authorization-review \ .claude/skills/laravel-authorization-review
Use ~/.claude/skills/ instead to install it globally (every project). No npx? Clone the repo and copy the skills/laravel-authorization-review folder into .claude/skills/. Want every skill at once? Add the plugin marketplace (optional).
Start it inside your Laravel project folder (the one with artisan).
"review my authorization", "find IDOR in this app", "which routes have no auth?", "review authorization on the routes in this PR" — the skill activates automatically.
You get a coverage map and findings with proof. Nothing is changed for you — apply each fix on a branch, with tests.
route:list and your files contain;route:list anchor and use their own models (a future version may add them);It is not a pentest and not a security product: a report with no findings means "nothing broken in the layers checked", not "secure".
Full usage guide ↗ Example report ↗ SKILL.md source ↗ ← Back to library