agentsclimarketplace

Laravel security

Skill HamzaAlayed/laravel-claude-agents/skills/laravel-security

The Laravel security-review cookbook — STRIDE applied to Laravel primitives, the authn / authz / mass-assignment / upload / injection checklist, advisory lookup procedure, and the finding format. Use when threat-modeling a feature, reviewing a PR that touches auth / PII / billing / uploads / middleware, or triaging a suspected vulnerability. Findings only — fixes land with the owning builder after human awareness.From its SKILL.md

Install
npx -y skills add HamzaAlayed/laravel-claude-agents --skill laravel-security

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

4.7 KB, as published. Nobody here has run it

Laravel Security Review

Verify before asserting. Trace the exploit path (route → middleware, incl. #[Middleware]/#[Authorize] controller attributes on L13 → FormRequest → Policy → query) before reporting — a grep over routes/middleware alone misses attribute-based coverage. Unverifiable → mark Suspected + the evidence needed. Never invent CVE IDs or CVSS scores — cite only advisories actually fetched.

STRIDE on Laravel primitives

ThreatLaravel check
SpoofingGuard per route group correct (config/auth.php); session fixation (Session::regenerate() on login); Sanctum SPA cookie domain matches frontend origin; password-reset tokens single-use + time-bound
TamperingMass assignment ($fillable deliberate, no $guarded = [] on user input); hidden-field trust; signed URLs (URL::signedRoute()) for out-of-band links; Livewire scalar props client-settable → #[Locked] on IDs used in authz
RepudiationState-changing actions logged with actor + tenant; audit records append-only
Info disclosureAPI Resources (never raw models — hidden columns leak); error pages / debug mode (APP_DEBUG prod), stack traces in responses, source maps; logs redact PII + secrets
DoSUnbounded queries (no pagination), upload size/count limits, queue flooding, missing RateLimiter::for() on auth / OTP / expensive endpoints
ElevationPolicy on every state-changing route (can: middleware, FormRequest authorize(), Gate::authorize(), or L13 #[Authorize] attribute); policy registration includes #[UsePolicy] on models alongside auto-discovery; IDOR — route-model binding scoped (->scopeBindings() or tenant global scope); Gate::before not granting wholesale

Document trust boundaries crossed + data sensitivity at each.

The checklist beyond STRIDE

  • SQL / query: no DB::raw with concatenated input — bindings only; orderBy(request('sort')) is injection — allowlist the column.
  • XSS: {!! !!} only with a written safety argument; user HTML → sanitize (mews/purifier or equivalent); JSON in Blade via @js / Js::from.
  • Uploads: validate mimetypes: (server-side, not extension), size; store on non-public disk; never trust client filename (hashName()); images → strip EXIF where PII-relevant.
  • CSRF: web routes covered; deliberate exceptions (preventRequestForgery(except:) in bootstrap/app.php on L13 — validateCsrfTokens is the deprecated L11/12 alias, middleware class renamed VerifyCsrfToken → PreventRequestForgery) each justified. L13 verifies origin via Sec-Fetch-Site first, token fallback second — HTTPS-only, so check reverse proxies/CDNs don't strip the header, and test exclusions reference PreventRequestForgery::class.
  • Secrets: never in repo, .env.* committed, or logs. config() only — env() outside config/*.php breaks under cache and hints at drift. Scan diffs: gitleaks detect. Suspected APP_KEY exposure → rotate via APP_PREVIOUS_KEYS (graceful re-encryption), never an ad-hoc key swap that bricks encrypted data and sessions.
  • Jobs / queues: PII-bearing jobs ShouldBeEncrypted; failed-job payloads (failed_jobs.payload) hold serialized PII — retention policy exists.
  • Headers / CORS: config/cors.php origins explicit (no * with credentials) — file absent means unpublished defaults apply; php artisan config:publish cors before asserting origins. Cookies Secure, HttpOnly, SameSite.

Advisory lookup

  1. composer audit (uses the packagist advisory DB) — zero known-vulnerable deps to pass.
  2. For a specific package/version: GitHub Security Advisories + the package's own security policy. Fetch, don't recall.
  3. Framework CVEs: laravel/framework security releases — check the project's exact major is still patched.

Finding format

One finding = severity (CVSS 4.0 estimate — 3.1 when that's all the advisory carries — or Critical/High/Med/Low + why) + OWASP Top 10:2025 tag + CWE ID · exploit path (concrete route/file:line chain) · blast radius (data / tenants affected) · remediation naming the Laravel primitive ("add OrderPolicy::update + can:update,order on the route", not "add authorization"). Sort by severity. Suspected section separate from Confirmed.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.