asyrafhussin/agent-skillsMIT14 files

Laravel Owasp Security

OWASP Top 10 security audit and secure coding guidelines for Laravel + React/Inertia.js applications. Use when auditing for vulnerabilities ("run OWASP audit", "security review", "check my app security") or writing secure Laravel code involving auth, payments, file uploads, or API design. Triggers on security-related tasks, payment handling, authentication, or any request to audit a Laravel codebase.

Specification
Skill ID
asyrafhussin/agent-skills/laravel-owasp-security
Publisher
asyrafhussin
Repository
agent-skills
Installs
0
Files
14
License
MIT
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

asyrafhussin/agent-skills/laravel-owasp-securityInstalls these files
  • AGENTS.md
  • README.md
  • SKILL.md
  • metadata.json
  • rules/_sections.md
  • rules/_template.md
  • rules/sec-authentication-rate-limiting.md
  • rules/sec-broken-access-control.md
  • rules/sec-cryptographic-failures.md
  • rules/sec-csrf-protection.md
  • rules/sec-inertia-data-exposure.md
  • rules/sec-injection-prevention.md
  • rules/sec-security-misconfiguration.md
  • rules/sec-xss-react-inertia.md

What this skill tells the agent

Laravel OWASP Security

Dual-purpose security skill for Laravel 13 + React/Inertia.js applications. Run a full OWASP Top 10 audit against a codebase, or use as a secure coding reference when building features.

How to Audit

Step 1: Detect Stack

Check if the project uses React + Inertia.js by looking for:

  • app/Http/Middleware/HandleInertiaRequests.php exists
  • resources/js/ contains .tsx or .jsx files
  • inertiajs/inertia-laravel in composer.json
  • @inertiajs/react in package.json

If detected, state at the top of the report:

"React + Inertia.js detected — Laravel OWASP checklist AND React/Inertia security checks will both be applied."

If not detected, state:

"No React/Inertia.js detected — applying Laravel OWASP checklist only."

Step 2: Determine Scope

  • If arguments provided ($ARGUMENTS): review only those files or features
  • If no arguments: review the entire codebase

Step 3: Run Checklist

Work through every item below. For each, output:

  • PASS — brief confirmation of what was verified
  • FAIL — exact file:line, a description of the vulnerability (do NOT reproduce any code, values, API keys, tokens, or .env contents from the file), and a fix recommendation
  • N/A — if the check does not apply to this project

OWASP Top 10 Checklist

1. Broken Access Control (A01:2021)

  • [ ] Middleware protects all route groups by role (auth, role:admin, etc.)
  • [ ] Resource queries scoped to authenticated user — ->where('user_id', auth()->id())
  • [ ] No direct object reference without ownership check
  • [ ] Gates and Policies used to authorize resource access
  • [ ] Frontend role checks are mirrored server-side — never rely on React UI checks alone

2. Cryptographic Failures (A02:2021)

  • [ ] Passwords hashed with Hash::make() or 'hashed' Eloquent cast — never stored as plaintext
  • [ ] No MD5 or SHA1 used for password hashing
  • [ ] Sensitive fields (API keys, secrets) encrypted with Crypt::encryptString() or 'encrypted' Eloquent cast
  • [ ] APP_KEY is long, random, and unique per environment
  • [ ] Signed URLs (URL::signedRoute()) used for sensitive one-time actions (password reset, email verify)

3. Injection (A03:2021)

SQL & Mass Assignment:

  • [ ] No string concatenation in whereRaw(), selectRaw(), orderByRaw() — use ? bindings
  • [ ] Column names never derived from user input without a whitelist
  • [ ] No $request->all() passed directly to create(), fill(), or update()
  • [ ] No forceFill() or forceCreate() with unvalidated user input
  • [ ] Models define $fillable explicitly — not $guarded = []
  • [ ] Controllers use $request->validated() for mass operations

XSS — Blade & React:

  • [ ] No {!! $userInput !!} in Blade templates with untrusted data
  • [ ] {{ }} used for all user-supplied Blade output
  • [ ] No dangerouslySetInnerHTML in React without DOMPurify.sanitize() first
  • [ ] href and src attributes not set from unvalidated user input
  • [ ] No eval(), new Function(), or setTimeout(string) with user-controlled strings
  • [ ] External CDN scripts use Subresource Integrity (integrity="sha384-...")

4. Insecure Design (A04:2021)

  • [ ] Business logic enforced server-side — prices, totals, and discounts never trusted from client input
  • [ ] Sensitive operations require secondary confirmation (e.g. password re-entry for account deletion)
  • [ ] No mass action endpoints without per-item authorization check
  • [ ] Admin-only features isolated behind separate middleware — not just hidden in the UI
  • [ ] Payment amounts and enrollment states calculated server-side, not passed as form inputs

5. Security Misconfiguration (A05:2021)

  • [ ] APP_DEBUG=false in production
  • [ ] .env is in .gitignore and never committed
  • [ ] Database uses a restricted user — not root/admin — in production
  • [ ] storage/ and bootstrap/cache/ have correct permissions (not world-writable)
  • [ ] APP_KEY is set and unique per environment
  • [ ] CORS allowed_origins is not ['*'] for authenticated API routes

6. Vulnerable & Outdated Components (A06:2021)

  • [ ] composer audit passes with no known CVEs
  • [ ] npm audit passes with no known CVEs
  • [ ] Laravel framework is on a supported version

7. Identification & Authentication Failures (A07:2021)

Auth:

  • [ ] Using Laravel Breeze, Fortify, or Jetstream — not custom-rolled auth
  • [ ] Passwords hashed with bcrypt or argon2 (Laravel default)
  • [ ] Login route rate limited — throttle middleware or RateLimiter in LoginRequest
  • [ ] Password reset and email verification routes rate limited
  • [ ] Payment and sensitive action routes have appropriate rate limits
  • [ ] session()->regenerate() called after successful login

Cookie & Session:

  • [ ] http_only = true in config/session.php
  • [ ] same_site = lax or strict in config/session.php
  • [ ] secure = true or null (auto for HTTPS) in config/session.php
  • [ ] lifetime is a reasonable value (15–30 min recommended for most apps)
  • [ ] domain = null unless subdomains are needed
  • [ ] EncryptCookies middleware is in the web group

8. Software & Data Integrity Failures (A08:2021)

CSRF:

  • [ ] VerifyCsrfToken middleware active in the web group
  • [ ] Only stateless routes (webhooks, external callbacks) are excluded from CSRF
  • [ ] @csrf directive used in all non-Inertia POST forms
  • [ ] Excluded routes in validateCsrfTokens(except: [...]) are justified

Deserialization:

  • [ ] No unserialize($request->input(...))
  • [ ] No eval($request->input(...))
  • [ ] No extract($request->all())

9. Security Logging & Monitoring Failures (A09:2021)

  • [ ] Failed login attempts logged with IP and identifier
  • [ ] Payment failures and exceptions logged
  • [ ] Log entries do not contain raw passwords or secrets
  • [ ] Monitoring in place (Laravel Telescope, Sentry, or similar)

10. Server-Side Request Forgery — SSRF (A10:2021)

  • [ ] No Http::get($request->input('url')) with unvalidated URLs
  • [ ] User-supplied URLs validated against an allowlist or scheme check
  • [ ] Internal network addresses blocked from user-supplied URLs

Additional Checks

Not part of the OWASP Top 10 but critical for Laravel applications.

Command Injection & Dangerous Functions

  • [ ] No exec(), shell_exec(), system(), passthru() with user input
  • [ ] No open redirects — no redirect($request->input('url')) with unvalidated URLs
  • [ ] File uploads validate mimes:, max: — filenames never derived from raw user input

Security Headers

  • [ ] Content-Security-Policy set — with nonces (Vite::useCspNonce()) if possible
  • [ ] X-Frame-Options set
  • [ ] X-Content-Type-Options set
  • [ ] Strict-Transport-Security set for HTTPS
  • [ ] Referrer-Policy set
  • [ ] Permissions-Policy set

React + Inertia.js Checks

Only run if React + Inertia.js detected in Step 1.

R1. XSS in React Components

  • [ ] No dangerouslySetInnerHTML={{ __html: userInput }} without DOMPurify.sanitize() first
  • [ ] href and src attributes not set from unvalidated user input — javascript: URLs execute scripts
  • [ ] No eval(), new Function(), or setTimeout(string) with user-controlled strings
  • [ ] Links from user input validate scheme (https:// or http:// only)

R2. Inertia.js Data Exposure (Critical)

  • [ ] HandleInertiaRequests::share() does NOT expose passwords, tokens, or internal-only flags
  • [ ] Controllers use ->only([...]) or API Resources — not raw model toArray()
  • [ ] All Inertia props are treated as public — visible in data-page HTML attribute on initial load
  • [ ] Payment secret keys and admin-only credentials are never passed as Inertia props
  • [ ] Inertia v2 History Encryption enabled for pages with sensitive data

R3. CSRF in Inertia.js

  • [ ] Inertia X-XSRF-TOKEN header not disabled

Use this skill in a project

Open any RiverX project, search the Skills panel for asyrafhussin/agent-skills/laravel-owasp-security, and install it in one click.

Use this skill