Everything-claude-code laravel-security
Laravel security best practices for authn/authz, validation, CSRF, mass assignment, file uploads, secrets, rate limiting, and secure deployment.
install
source · Clone the upstream repo
git clone https://github.com/affaan-m/everything-claude-code
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/affaan-m/everything-claude-code "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/laravel-security" ~/.claude/skills/affaan-m-everything-claude-code-laravel-security-bffcb2 && rm -rf "$T"
manifest:
skills/laravel-security/SKILL.mdsource content
Laravel Security Best Practices
Comprehensive security guidance for Laravel applications to protect against common vulnerabilities.
When to Activate
- Adding authentication or authorization
- Handling user input and file uploads
- Building new API endpoints
- Managing secrets and environment settings
- Hardening production deployments
How It Works
- Middleware provides baseline protections (CSRF via
, security headers viaVerifyCsrfToken
).SecurityHeaders - Guards and policies enforce access control (
,auth:sanctum
, policy middleware).$this->authorize - Form Requests validate and shape input (
) before it reaches services.UploadInvoiceRequest - Rate limiting adds abuse protection (
) alongside auth controls.RateLimiter::for('login') - Data safety comes from encrypted casts, mass-assignment guards, and signed routes (
+URL::temporarySignedRoute
middleware).signed
Core Security Settings
in productionAPP_DEBUG=false
must be set and rotated on compromiseAPP_KEY- Set
andSESSION_SECURE_COOKIE=true
(orSESSION_SAME_SITE=lax
for sensitive apps)strict - Configure trusted proxies for correct HTTPS detection
Session and Cookie Hardening
- Set
to prevent JavaScript accessSESSION_HTTP_ONLY=true - Use
for high-risk flowsSESSION_SAME_SITE=strict - Regenerate sessions on login and privilege changes
Authentication and Tokens
- Use Laravel Sanctum or Passport for API auth
- Prefer short-lived tokens with refresh flows for sensitive data
- Revoke tokens on logout and compromised accounts
Example route protection:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::middleware('auth:sanctum')->get('/me', function (Request $request) { return $request->user(); });
Password Security
- Hash passwords with
and never store plaintextHash::make() - Use Laravel's password broker for reset flows
use Illuminate\Support\Facades\Hash; use Illuminate\Validation\Rules\Password; $validated = $request->validate([ 'password' => ['required', 'string', Password::min(12)->letters()->mixedCase()->numbers()->symbols()], ]); $user->update(['password' => Hash::make($validated['password'])]);
Authorization: Policies and Gates
- Use policies for model-level authorization
- Enforce authorization in controllers and services
$this->authorize('update', $project);
Use policy middleware for route-level enforcement:
use Illuminate\Support\Facades\Route; Route::put('/projects/{project}', [ProjectController::class, 'update']) ->middleware(['auth:sanctum', 'can:update,project']);
Validation and Data Sanitization
- Always validate inputs with Form Requests
- Use strict validation rules and type checks
- Never trust request payloads for derived fields
Mass Assignment Protection
- Use
or$fillable
and avoid$guardedModel::unguard() - Prefer DTOs or explicit attribute mapping
SQL Injection Prevention
- Use Eloquent or query builder parameter binding
- Avoid raw SQL unless strictly necessary
DB::select('select * from users where email = ?', [$email]);
XSS Prevention
- Blade escapes output by default (
){{ }} - Use
only for trusted, sanitized HTML{!! !!} - Sanitize rich text with a dedicated library
CSRF Protection
- Keep
middleware enabledVerifyCsrfToken - Include
in forms and send XSRF tokens for SPA requests@csrf
For SPA authentication with Sanctum, ensure stateful requests are configured:
// config/sanctum.php 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost')),
File Upload Safety
- Validate file size, MIME type, and extension
- Store uploads outside the public path when possible
- Scan files for malware if required
final class UploadInvoiceRequest extends FormRequest { public function authorize(): bool { return (bool) $this->user()?->can('upload-invoice'); } public function rules(): array { return [ 'invoice' => ['required', 'file', 'mimes:pdf', 'max:5120'], ]; } }
$path = $request->file('invoice')->store( 'invoices', config('filesystems.private_disk', 'local') // set this to a non-public disk );
Rate Limiting
- Apply
middleware on auth and write endpointsthrottle - Use stricter limits for login, password reset, and OTP
use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Http\Request; use Illuminate\Support\Facades\RateLimiter; RateLimiter::for('login', function (Request $request) { return [ Limit::perMinute(5)->by($request->ip()), Limit::perMinute(5)->by(strtolower((string) $request->input('email'))), ]; });
Secrets and Credentials
- Never commit secrets to source control
- Use environment variables and secret managers
- Rotate keys after exposure and invalidate sessions
Encrypted Attributes
Use encrypted casts for sensitive columns at rest.
protected $casts = [ 'api_token' => 'encrypted', ];
Security Headers
- Add CSP, HSTS, and frame protection where appropriate
- Use trusted proxy configuration to enforce HTTPS redirects
Example middleware to set headers:
use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; final class SecurityHeaders { public function handle(Request $request, \Closure $next): Response { $response = $next($request); $response->headers->add([ 'Content-Security-Policy' => "default-src 'self'", 'Strict-Transport-Security' => 'max-age=31536000', // add includeSubDomains/preload only when all subdomains are HTTPS 'X-Frame-Options' => 'DENY', 'X-Content-Type-Options' => 'nosniff', 'Referrer-Policy' => 'no-referrer', ]); return $response; } }
CORS and API Exposure
- Restrict origins in
config/cors.php - Avoid wildcard origins for authenticated routes
// config/cors.php return [ 'paths' => ['api/*', 'sanctum/csrf-cookie'], 'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], 'allowed_origins' => ['https://app.example.com'], 'allowed_headers' => [ 'Content-Type', 'Authorization', 'X-Requested-With', 'X-XSRF-TOKEN', 'X-CSRF-TOKEN', ], 'supports_credentials' => true, ];
Logging and PII
- Never log passwords, tokens, or full card data
- Redact sensitive fields in structured logs
use Illuminate\Support\Facades\Log; Log::info('User updated profile', [ 'user_id' => $user->id, 'email' => '[REDACTED]', 'token' => '[REDACTED]', ]);
Dependency Security
- Run
regularlycomposer audit - Pin dependencies with care and update promptly on CVEs
Signed URLs
Use signed routes for temporary, tamper-proof links.
use Illuminate\Support\Facades\URL; $url = URL::temporarySignedRoute( 'downloads.invoice', now()->addMinutes(15), ['invoice' => $invoice->id] );
use Illuminate\Support\Facades\Route; Route::get('/invoices/{invoice}/download', [InvoiceController::class, 'download']) ->name('downloads.invoice') ->middleware('signed');