laravel-security

Auto-invoked skill

Security audits for OWASP vulnerabilities and fixes

Trigger Keywords

This skill automatically activates when Claude detects these keywords:

security XSS SQL injection CSRF OWASP vulnerability

Overview

The laravel-security skill provides expertise for identifying and fixing security vulnerabilities. It covers OWASP Top 10 issues, Laravel-specific security patterns, and best practices for hardening applications.

What This Skill Provides

  • OWASP Top 10 - Detection and fixes for common vulnerabilities
  • Input Validation - Proper sanitization and escaping
  • Authentication Security - Password policies, brute force protection
  • CSRF/XSS Prevention - Token verification, output encoding
  • SQL Injection - Parameterized queries, Eloquent safety
  • Security Headers - CSP, HSTS, X-Frame-Options

Example Conversations

# Finding vulnerabilities
"Audit my authentication system for security issues"

# Fixing XSS
"My blade templates might be vulnerable to XSS attacks"

# SQL injection concerns
"Is this raw query safe from SQL injection?"

# Security headers
"Help me configure security headers for production"

Common Vulnerabilities & Fixes

// BAD: SQL Injection
$users = DB::select("SELECT * FROM users WHERE name = '$name'");

// GOOD: Parameterized query
$users = DB::select("SELECT * FROM users WHERE name = ?", [$name]);

// BETTER: Use Eloquent
$users = User::where('name', $name)->get();

// BAD: XSS vulnerability
{!! $userInput !!}

// GOOD: Escaped output


// BAD: Mass assignment vulnerability
$user = User::create($request->all());

// GOOD: Explicit fields
$user = User::create($request->only(['name', 'email']));

// Or use $fillable in model

Security Middleware

// Add security headers
class SecurityHeaders
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        $response->headers->set('X-Content-Type-Options', 'nosniff');
        $response->headers->set('X-Frame-Options', 'SAMEORIGIN');
        $response->headers->set('X-XSS-Protection', '1; mode=block');
        $response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');

        return $response;
    }
}

OWASP Top 10 Checklist

Vulnerability Laravel Protection
Injection Eloquent, prepared statements
Broken Authentication Built-in auth, throttling
XSS Blade auto-escaping
CSRF @csrf directive, VerifyCsrfToken middleware
Mass Assignment $fillable / $guarded properties

Common Pitfalls

// 1. Using $guarded = [] - Allows mass assignment attacks
// BAD
protected $guarded = [];

// GOOD - explicit fillable
protected $fillable = ['name', 'email'];

// 2. Trusting User Input in Raw Queries
// DANGEROUS
DB::statement("UPDATE users SET role = '{$request->role}'");

// Safe
DB::statement('UPDATE users SET role = ?', [$request->role]);

// 3. Exposing Sensitive Data in Errors
// config/app.php - in production
'debug' => false,

// 4. Missing Authorization Checks
// BAD - no auth check
public function update(Request $request, Post $post)
{
    $post->update($request->all());
}

// GOOD
public function update(Request $request, Post $post)
{
    $this->authorize('update', $post);
    $post->update($request->validated());
}

// 5. Storing Tokens/Secrets in Logs
// BAD
Log::info('Payment processed', $request->all());

// GOOD
Log::info('Payment processed', [
    'amount' => $request->amount,
    'card_last4' => substr($request->card_number, -4),
]);

Package Integration

  • spatie/laravel-permission - Role-based access control
  • laravel/sanctum - API token authentication
  • laravel/passport - OAuth2 server
  • paragonie/ciphersweet - Searchable encryption

Best Practices

  • Never store secrets in code
  • Use .env for sensitive config
  • Keep dependencies updated
  • Enable HTTPS in production
  • Use prepared statements
  • Validate all input
  • Log security events
  • Use Content Security Policy
  • Regular security audits with composer audit

Password Validation

use Illuminate\Validation\Rules\Password;

$request->validate([
    'password' => [
        'required',
        'confirmed',
        Password::min(8)
            ->mixedCase()
            ->numbers()
            ->symbols()
            ->uncompromised(), // Check against data breaches
    ],
]);

Related Commands

Related Agent