Laravel Authentication Security Checklist

Harden your Laravel authentication system against brute-force attacks, session hijacking, and credential theft with this security checklist.

Progress
0 / 15 completed

Password & Credential Security

Enforce minimum password length of 8+ characters

Use Laravel's Password::min(8) validation rule. Consider requiring 12+ characters for sensitive applications. Longer passwords are significantly harder to crack than short complex passwords.

Use bcrypt or Argon2id for password hashing

Laravel uses bcrypt by default, which is secure. For higher security, switch to Argon2id in config/hashing.php. Never use MD5, SHA-1, or SHA-256 for password hashing — they are too fast to resist brute-force.

Implement password breach checking

Use Laravel's Password::uncompromised() validation rule to check passwords against the Have I Been Pwned database. This prevents users from choosing passwords that are already in known breach databases.

Never store passwords or secrets in plain text

This includes log files, email notifications, and admin panels. Ensure password fields are never logged, and use the hidden cast or $hidden property on the User model.

Implement account lockout after failed attempts

Use Laravel's built-in login throttling or implement a lockout mechanism that temporarily blocks login attempts after 5 consecutive failures. This prevents brute-force attacks.

Session Security

Set session cookie to secure, httponly, and samesite

In config/session.php, set secure to true (HTTPS only), http_only to true (no JavaScript access), and same_site to lax or strict. This prevents session theft via XSS and CSRF.

Regenerate session ID after login

Call session()->regenerate() after successful authentication to prevent session fixation attacks. Laravel's built-in authentication does this automatically, but verify it if you have custom login logic.

Set appropriate session lifetime

Configure lifetime in config/session.php based on your application's sensitivity. Financial applications should use shorter lifetimes (15-30 minutes). Set expire_on_close to true for sensitive applications.

Use database or Redis session driver in production

The file session driver works for development but can have issues with load balancers and does not support easy session management. Use database or Redis for production deployments.

Invalidate all sessions on password change

When a user changes their password, invalidate all other active sessions. Laravel provides Auth::logoutOtherDevices($password) for this purpose. This ensures compromised sessions are terminated.

Multi-Factor Authentication & Advanced Security

Implement two-factor authentication (2FA)

Use Laravel Fortify or Jetstream's built-in 2FA support. TOTP-based 2FA (Google Authenticator, Authy) adds a second layer that protects accounts even if passwords are compromised.

Provide recovery codes for 2FA

Generate one-time recovery codes that users can store safely for account recovery if they lose access to their 2FA device. Laravel Fortify handles this automatically.

Rate limit password reset and email verification requests

Apply throttle middleware to password reset and email verification endpoints. Without rate limiting, these endpoints can be used for email bombing and user enumeration.

Use generic error messages for authentication failures

Return "Invalid credentials" instead of "User not found" or "Incorrect password". Specific messages allow attackers to enumerate valid email addresses and usernames.

Log authentication events for audit trails

Log successful logins, failed attempts, password changes, and 2FA events. Include IP addresses and user agents. This data is essential for detecting unauthorized access and forensic analysis.

Frequently Asked Questions

Is bcrypt still secure for password hashing in Laravel?

Yes. Bcrypt remains a secure choice for password hashing. It is intentionally slow, which makes brute-force attacks impractical. Laravel's default bcrypt cost factor of 12 is appropriate for most applications. Argon2id offers additional resistance to GPU-based attacks if needed.

Should I implement 2FA for all users or just admins?

At minimum, require 2FA for admin and privileged accounts. For applications handling sensitive data (financial, healthcare, personal), offer 2FA to all users and strongly encourage or require it. Laravel Jetstream makes adding 2FA straightforward.

How do I prevent user enumeration through login and password reset forms?

Use the same response for valid and invalid email addresses. For login, return "Invalid credentials" regardless of whether the email exists. For password reset, always say "If an account exists, we've sent a reset link." Laravel's default password reset already follows this pattern.

Related Fix Guides

Other Checklists

Automate These Checks with StackShield

Stop running through checklists manually. StackShield continuously monitors your Laravel application for the security issues that matter most.

Start Free Trial