Strengthening Your Laravel 12 App Against Modern Threats

Laravel 12 offers developers a powerful and expressive framework with a solid foundation for secure application development. However, even with these strong defaults, real-world applications remain vulnerable when security is overlooked or poorly implemented.

This post outlines practical, actionable security practices to help you harden your Laravel app against common threats — including input validation, secure file uploads, HTTPS, and more. Whether you're maintaining a legacy app or launching something new, these steps will guide you towards a secure-by-default mindset.

laravel security checklist image

1. Input Validation and Sanitisation

Never trust incoming data — even if it originates from your own frontend or API consumers.

Laravel makes validation straightforward using Form Request classes and the Validator facade. Always validate all incoming data, regardless of the source.

$request->validate([
    'email' => 'required|email|exists:users,email',
    'age' => 'nullable|integer|min:18',
]);

To sanitise data before validation, use prepareForValidation() in Form Requests:

protected function prepareForValidation(): void
{
    $this->merge([
        'email' => strtolower($this->email),
    ]);
}

For larger applications, consider using Data Transfer Objects (DTOs) to structure and sanitise validated data consistently.

2. Authentication and Authorisation

Always implement robust access control — and for most Laravel applications, the Spatie Laravel Permission package is the industry standard.

Define roles and permissions centrally and attach them to users:

$user->assignRole('editor');
$user->givePermissionTo('edit articles');

Protect routes with middleware:

Route::post('/admin')->middleware('permission:access admin panel');

Use Blade directives in views:

@can('edit articles')
    Edit Article
@endcan

For sensitive actions like login or password reset, apply rate-limiting:

Route::post('/login')->middleware('throttle:5,1');

You may also wish to implement Multi-Factor Authentication (MFA) using Laravel Fortify or a custom solution for high-privilege accounts.

3. Enforce HTTPS and Secure Headers

Securing data transmission over HTTPS is essential for protecting sensitive user information. Beyond that, modern browsers support several security-related HTTP headers that can further reduce your application's exposure to common web vulnerabilities.

Force HTTPS

Redirect all HTTP traffic to HTTPS to ensure encrypted connections:

public function handle($request, Closure $next)
{
    if (!$request->secure()) {
        return redirect()->secure($request->getRequestUri());
    }

    return $next($request);
}

Key HTTP Security Headers

Here’s a breakdown of the most important headers you should consider adding:

Applying Headers

You can set these headers globally using custom middleware or use a package like bepsvpt/secure-headers to manage them with a config file:

composer require bepsvpt/secure-headers

Then publish the config and adjust:

php artisan vendor:publish --provider="Bepsvpt\SecureHeaders\SecureHeadersServiceProvider"

These headers work together to strengthen client-side security, reduce browser-based threats, and demonstrate to users (and search engines) that your site is serious about protecting data.

4. Database Security and Mass Assignment

Avoid mass-assignment vulnerabilities by never blindly assigning request data:

// Risky
$user->update($request->all());

// Safer
$user->update($request->only(['name', 'email']));

Protect model properties using $fillable or $guarded:

protected $fillable = ['name', 'email'];

Use parameter binding in raw queries to prevent SQL injection:

DB::select('SELECT * FROM users WHERE email = ?', [$email]);

5. Secure File Uploads

File uploads are a common attack vector and must be tightly controlled.

Validate file type and size before storing:

$request->validate([
    'photo' => 'required|image|mimes:jpeg,png|max:2048',
]);

Rename files to avoid malicious filenames or collisions:

$filename = Str::uuid() . '.' . $file->getClientOriginalExtension();

Store sensitive files in non-public disks and serve via signed URLs:

URL::temporarySignedRoute('download', now()->addMinutes(10), ['file' => $id]);

6. CSRF, XSS, and SQL Injection

Laravel automatically protects against CSRF via tokens. Ensure you use @csrf in all Blade forms.

To prevent XSS attacks:

Avoid SQL injection by never interpolating input into queries. Use bindings:

DB::select('SELECT * FROM users WHERE email = ?', [$email]);

7. Cookies and Session Security

In config/session.php, enforce strict security settings:

'secure' => env('SESSION_SECURE_COOKIE', true),
'http_only' => true,
'same_site' => 'lax',

Use Redis or database drivers in production instead of file-based sessions:

SESSION_DRIVER=redis

These settings help mitigate session hijacking and CSRF.

8. Production Security Checklist

Before going live, review the following:

Conclusion

Laravel 12 provides strong security defaults, but it’s your responsibility to make informed decisions when writing application logic. Secure apps come from conscious habits: validate data, reduce surface area, restrict access, and monitor sensitive areas.

When security is prioritised from the beginning, your application becomes easier to defend and scale. Build securely — by default.