Laravel ships with many security features enabled by default, but production applications require deliberate configuration, dependency updates, and code patterns that prevent common OWASP vulnerabilities.
Authentication and Session Security
Strong authentication is the foundation. Use bcrypt or argon hashing, session encryption, and secure cookies.
Multi-factor authentication packages like laravel/fortify with two-factor enabled protect high-value accounts.
Step 1: Keep APP_KEY and credentials secret
APP_KEY encrypts cookies and signed URLs. Rotate keys only with a planned re-login strategy.
Store secrets in environment variables or secret managers—not in git repositories.
APP_KEY=base64:...
APP_DEBUG=false
Step 2: Enable CSRF protection on web routes
Web middleware group includes VerifyCsrfToken. Forms need @csrf directive or @csrf Blade helper.
Exclude webhooks from CSRF in VerifyCsrfToken $except array using exact URI paths.
@csrf
Step 3: Configure secure session cookies
Set SESSION_SECURE_COOKIE=true behind HTTPS, SESSION_HTTP_ONLY=true, and same_site=lax or strict.
Short session lifetime limits exposure if a session token leaks.
SESSION_SECURE_COOKIE=true
SESSION_SAME_SITE=lax
Step 4: Apply rate limiting to auth routes
In RouteServiceProvider or bootstrap/app.php use RateLimiter::for('login', fn($r) => Limit::perMinute(5)).
Throttle API routes with throttle:api middleware to mitigate brute force and scraping.
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)->by($request->ip());
});
Input Validation and Data Access
Never trust user input. Validation, authorization policies, and Eloquent parameter binding block most injection attacks.
Mass assignment vulnerabilities occur when request data fills protected model attributes unexpectedly.
Step 1: Use $fillable or $guarded on models
Define protected $fillable = ['name', 'email'] or guarded = ['id', 'is_admin'].
Never leave both empty. For extra safety use $request->validated() with explicit keys.
protected $fillable = ['name', 'email', 'bio'];
Step 2: Authorize with policies and gates
Create php artisan make:policy PostPolicy –model=Post. Call $this->authorize('update', $post) in controllers.
Policies keep authorization logic out of controllers and make security rules testable.
$this->authorize('update', $post);
Step 3: Prevent SQL injection with Eloquent
Use Eloquent and query builder bindings. Never concatenate user input into DB::raw() strings.
When raw SQL is required, bind parameters: DB::select('select * from users where id = ?', [$id]).
User::where('email', $email)->first();
Step 4: Sanitize HTML output
Blade {{ }} escapes HTML by default. Use {!! !!} only for trusted content.
Purify rich text with HTMLPurifier or strip tags server-side before storage.
{{ $user->name }}
Headers, Dependencies, and Auditing
Security headers reduce XSS and clickjacking risk. Composer audit catches known CVEs in dependencies.
Logging and intrusion detection help respond to incidents quickly.
Step 1: Add security headers middleware
Packages like spatie/laravel-csp configure Content-Security-Policy. Set X-Frame-Options DENY and HSTS.
Test headers with securityheaders.com after deploy.
composer require spatie/laravel-csp
Step 2: Run composer audit regularly
composer audit lists known vulnerabilities. Integrate into CI to fail builds on critical CVEs.
Keep laravel/framework and symfony components updated with composer update on a schedule.
composer audit
Step 3: Log authentication failures
Log failed logins with IP and user agent. Alert on spikes indicating credential stuffing.
Never log passwords or full credit card numbers—mask sensitive fields.
Log::warning('Failed login', ['email' => $email, 'ip' => $request->ip()]);
Step 4: Backup and disaster recovery
Encrypt database backups at rest. Test restore procedures quarterly.
Document incident response contacts and Laravel-specific steps like pausing queues during breaches.
php artisan backup:run
Aadyanex builds production-ready Laravel applications with clean architecture, secure APIs, and long-term support.
