Skip to main content
skill CX Codex

laravel-owasp-security — Claude Code skill: features and setup

Audits Laravel 13 and React/Inertia.js codebases against the OWASP Top 10 checklist and assists with secure implementation of auth, payments, or APIs.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add AsyrafHussin/agent-skills --skill laravel-owasp-security -a claude-code
Open on GitHub

What laravel-owasp-security does

The skill audits codebases or guides secure coding during development. It first inspects the project for React and Inertia.js using files in resources/js/ and dependencies in composer.json. When Inertia is present, the agent checks frontend safety alongside backend rules.

The audit covers the OWASP Top 10 categories. It checks for missing route middleware, unsafe Eloquent raw queries, and unescaped output in Blade or React. Every finding includes a file location and a remediation tip. To prevent credential leaks, the output hides environment variables and secrets. This tool requires PHP 8.3+ and Laravel 13.x. Older stacks may hit false positives.

What it helps with

  • detect SQL injection risks in raw Eloquent queries
  • audit access control middleware, gates, and policies
  • check session and cookie security configurations
  • spot XSS risks in React components and Blade views

Example prompts for the agent

  • Run OWASP audit on my payment controllers
  • Check my app security against the OWASP checklist
  • Review our auth and session configuration for vulnerabilities

How to install laravel-owasp-security

1Skills CLI (Vercel)

npx skills add AsyrafHussin/agent-skills --skill laravel-owasp-security -a claude-code

2Manually: put the files in place

~/.claude/skills/laravel-owasp-security/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/laravel-owasp-security/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about laravel-owasp-security

How to install laravel-owasp-security in Claude Code?

Run npx skills add AsyrafHussin/agent-skills --skill laravel-owasp-security -a claude-code.

How does the skill detect Inertia and React?

It looks for HandleInertiaRequests.php, .tsx or .jsx files in resources/js/, and Inertia packages in composer.json and package.json. If found, it applies both Laravel and React checks.

Which PHP and Laravel versions does the skill target?

The skill metadata requires PHP 8.3+ and Laravel 13.x.

Source text

SKILL.md · MIT
---
name: laravel-owasp-security
description: 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.
license: MIT
metadata:
  author: AsyrafHussin
  version: "1.0.3"
  laravelVersion: "13.x"
  phpVersion: "8.3+"
---

# 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
- [ ] Custom `fetch` or `axios` calls include CSRF token manually if bypassing Inertia's router
- [ ] Webhook/callback routes are the ONLY CSRF-excluded routes

### R4. Authentication State in React

- [ ] `auth.user` Inertia prop excludes password hash, remember tokens, and 2FA secrets
- [ ] Role/permission checks enforced server-side — React checks are UI-only
- [ ] `auth.user` contains only fields the UI actually needs

### R5. Sensitive Data in Browser

- [ ] No API keys or secrets hardcoded in React components or TypeScript files
- [ ] No sensitive data in `localStorage` or `sessionStorage` — use HttpOnly cookies
- [ ] `VITE_*` env vars contain no secrets — they are public by design

### R6. Dependency Security

- [ ] `npm audit` passes with no high/critical CVEs in React or Inertia packages
- [ ] React is on a supported version
- [ ] Third-party component libraries reviewed for known CVEs

---

## Output Format

Structure the audit report as:

```
## Laravel OWASP Security Audit Report

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

### 1. Broken Access Control (A01:2021)
- **PASS** `app/Http/Middleware/RoleMiddleware.php` — role middleware applied to all route groups
- **FAIL** `app/Http/Controllers/PaymentController.php:42` — Payment model fetched without ownership check (direct object reference exposure). Fix: scope the query to the authenticated user.

[Continue for all 10 OWASP checks + Additional Checks + R1–R6 React/Inertia checks]

---

## Summary

### Critical Issues (fix immediately)
1. ...

### Warnings (fix soon)
1. ...

### Passed
X checks passed.

### Recommended Commands
composer audit
npm audit
```

---

## When to Apply for Guidance

Reference the rule files when:
- Implementing authentication or password handling
- Building payment or webhook integrations
- Writing file upload or download logic
- Designing admin or role-based access control
- Building API endpoints with user-supplied input
- Using `dangerouslySetInnerHTML` in React components
- Passing data from Laravel controllers to Inertia props

## Rule Categories by Priority

| Priority | Category | Impact | Rule File |
|----------|----------|--------|-----------|
| 1 | Broken Access Control | CRITICAL | `sec-broken-access-control` |
| 2 | Cryptographic Failures | CRITICAL | `sec-cryptographic-failures` |
| 3 | Injection Prevention | CRITICAL | `sec-injection-prevention` |
| 4 | XSS & React/Inertia | HIGH | `sec-xss-react-inertia` |
| 5 | CSRF Protection | HIGH | `sec-csrf-protection` |
| 6 | Security Misconfiguration | HIGH | `sec-security-misconfiguration` |
| 7 | Authentication & Rate Limiting | HIGH | `sec-authentication-rate-limiting` |
| 8 | Inertia Data Exposure | HIGH | `sec-inertia-data-exposure` |

## Quick Reference

### 1. Broken Access Control (CRITICAL)
- `sec-broken-access-control` — Middleware, ownership checks, policies, scoped queries

### 2. Cryptographic Failures (CRITICAL)
- `sec-cryptographic-failures` — Password hashing, encrypted casts, signed URLs

### 3. Injection Prevention (CRITICAL)
- `sec-injection-prevention` — SQL injection, mass assignment, raw query bindings

### 4. XSS & React/Inertia (HIGH)
- `sec-xss-react-inertia` — dangerouslySetInnerHTML, DOMPurify, href/src validation

### 5. CSRF Protection (HIGH)
- `sec-csrf-protection` — VerifyCsrfToken, webhook exclusions, Inertia CSRF

### 6. Security Misconfiguration (HIGH)
- `sec-security-misconfiguration` — APP_DEBUG, APP_KEY, security headers, CORS

### 7. Authentication & Rate Limiting (HIGH)
- `sec-authentication-rate-limiting` — Throttle, session regeneration, brute force prevention

### 8. Inertia Data Exposure (HIGH)
- `sec-inertia-data-exposure` — data-page attribute exposure, secret props, API Resources

## How to Use

Read individual rule files for detailed explanations and code examples:

```
rules/sec-broken-access-control.md
rules/sec-cryptographic-failures.md
rules/sec-injection-prevention.md
rules/sec-xss-react-inertia.md
rules/sec-csrf-protection.md
rules/sec-security-misconfiguration.md
rules/sec-authentication-rate-limiting.md
rules/sec-inertia-data-exposure.md
```

Each rule file contains:
- YAML frontmatter with metadata (title, impact, tags)
- Why it matters in Laravel/React context
- Incorrect code example with explanation
- Correct code example with fix
- Laravel 13 and PHP 8.3+ specific context

## Full Compiled Document

For the complete guide with all rules expanded: `AGENTS.md`

© AsyrafHussin · MIT · AsyrafHussin/agent-skills

Similar skills

All skills for Security →

From the same set17

laravel-best-practices A skill with 31 Laravel 13 rules covering architecture, Eloquent, controllers and validation. Useful when your agent writes PHP. CX Codex +1 2,300installs laravel-inertia-react A skill that hands your agent ready rules for Inertia pages, useForm handling and shared data across Laravel and React. CX Codex +1 1,900installs clean-code-principles A skill for architecture review and code quality: SOLID, DRY, KISS, design patterns. Useful when refactoring or weighing design decisions. CX Codex +1 1,800installs typescript-react-patterns A skill with 33 TypeScript rules for React: props, hooks, events, refs, generics and context. Useful when the agent writes components and fights type errors. CX Codex +1 1,100installs tailwind-best-practices Tailwind CSS v3.4+ and v4 conventions for AI coding agents. It guides responsive mobile-first layouts, dark mode, and migrations to version 4. CX Codex +1 941installs api-design-patterns A skill with 38 REST API rules covering resources, errors, security, pagination and versioning. Useful when an agent writes or reviews endpoints. CX Codex +1 929installs laravel-testing Guides AI agents in writing Laravel 13 feature and unit tests with Pest 4 or PHPUnit 12, covering model factories and service mocks. CX Codex +1 907installs testing-best-practices A rule set for unit and integration tests and TDD: 34 rules in 7 categories, TypeScript with Jest and Vitest. Useful while writing tests or reviewing someone else's. CX Codex +1 899installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor