Laravel Security Best Practices
March 20, 2024
•
22 min read
Introduction
Security is critical for any web application. Laravel provides many built-in security features, but understanding and properly implementing them is essential for protecting your application.
Authentication
Secure Password Storage
// Laravel automatically uses bcrypt
// Hash password
$user->password = Hash::make($request->password);
// Verify password
if (Hash::check($password, $user->password)) {
// Password correct
}
// Check if needs rehash
if (Hash::needsRehash($user->password)) {
$user->password = Hash::make($password);
$user->save();
}
Rate Limiting
// In routes/web.php
Route::middleware(['throttle:5,1'])->group(function () {
// 5 attempts per minute
});
// Custom throttle
Route::middleware('throttle:login')->group(function () {
Route::post('/login', [AuthController::class, 'login']);
});
Two-Factor Authentication
// Using Laravel Fortify
composer require laravel/fortify
// Enable 2FA in Fortify config
'features' => [
Features::twoFactorAuthentication(),
],
Input Validation
Form Request Validation
php artisan make:request StorePostRequest
// In StorePostRequest
public function rules(): array
{
return [
'title' => 'required|string|max:255',
'body' => 'required|string',
'category' => 'required|exists:categories,id',
'tags' => 'array',
'tags.*' => 'exists:tags,id',
'publish_at' => 'nullable|date|after:now',
];
}
Custom Validation
// Custom rule
php artisan make:rule Uppercase
// Validator::extend
Validator::extend('no_special_chars', function ($attribute, $value) {
return !preg_match('/[^a-zA-Z0-9]/', $value);
});
XSS & CSRF Protection
XSS Prevention
// Blade auto-escaping
{{ $user->name }}
// Outputs: <script>alert('xss')</script>
// Raw output (use carefully)
{!! $html !!}
// For HTML content
Clean::html($user->bio);
CSRF Protection
// CSRF Token
@csrf
// Or in JavaScript
// AJAX with CSRF
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
SQL Injection Prevention
Using Eloquent
// Safe: Eloquent ORM
$user = User::where('email', $email)->first();
// Safe: Query Builder with bindings
$users = DB::table('users')
->where('email', '=', $email)
->get();
// Unsafe (never do this!)
$users = DB::select("SELECT * FROM users WHERE email = '$email'");
Raw Queries with Bindings
// Safe: Parameterized query
DB::select('SELECT * FROM users WHERE id = ?', [$id]);
// Safe: Named bindings
DB::select('SELECT * FROM users WHERE id = :id', ['id' => $id]);
Encryption
Using Encryption
// Encrypt
$encrypted = Crypt::encryptString('secret data');
// Decrypt
$decrypted = Crypt::decryptString($encrypted);
// With IV (more secure)
$encrypted = encrypt($data);
$decrypted = decrypt($encrypted);
Hashing
// Hashing
$hash = Hash::make('password');
// Very secure (slower)
$hash = Hash::make('password', [
'rounds' => 12,
]);
Summary
Laravel provides robust security features, but proper implementation is essential. Always validate input, use proper authentication and authorization, and keep your dependencies updated.
For more Laravel tutorials, check out Laravel API Authentication and Laravel Docker Deployment.