Skip Content

A07: Authentication Failures (Blog)

What is an authentication failure?

Authentication Failures happen when login, session management, password resets, or token-based authentication are implemented or configured in a way that attackers can bypass, abuse, or persist access.

Laravel 12 starter kits apply login throttling by default, session IDs should be regenerated to prevent session fixation, Fortify supports two-factor authentication, and Laravel’s password broker handles password reset flows. Sanctum supports token abilities and is recommended for many first-party SPA/API cases.

Typical Laravel failure

  • Weak login throttling.
  • No MFA.
  • Bad password reset flow.
  • Long-lived sessions with poor invalidation.
  • Mixing SPA/API auth incorrectly.

Impact

  • Account takeover via credential stuffing / brute force.
  • Persistent sessions after password change or logout.
  • Reset-token abuse and takeover.
  • Privilege escalation when tokens/sessions are mixed incorrectly.

Laravel 12 remediation

  • Use Fortify or starter kits instead of inventing auth.
  • Enable 2FA.
  • Enforce password confirmation for sensitive account changes.
  • Regenerate sessions on login and invalidate on logout/password change.
  • For APIs, use Sanctum abilities (or Passport only when OAuth2 complexity is actually needed).
  • Separate browser session auth from token auth correctly.

For a blog:

  • Reading posts/comments should be public (no auth required).
  • Comment creation should require authentication (auth middleware / Form Request authorize).
  • Post creation should require stronger authorization (role/permission).

Concrete fix

Session hardening (prevent fixation, improve invalidation):

$request->session()->regenerate();
 
// On logout
// Auth::logout();
// $request->session()->invalidate();
// $request->session()->regenerateToken();

Fortify (enable 2FA at the framework level):

// config/fortify.php
 
use Laravel\Fortify\Features;
 
'features' => [
// ...
Features::twoFactorAuthentication(),
],

Passwords (use the password broker, not custom reset tokens):

use Illuminate\Support\Facades\Password;
 
Password::sendResetLink(['email' => $request->string('email')->toString()]);

Sanctum (token abilities for API access):

$token = $user->createToken('api', ['orders:read', 'orders:write'])->plainTextToken;

Design pattern angle

Keep browser session auth and API token auth as separate use-case entry points. Use an Action boundary that depends on an auth context (session user vs token user) instead of mixing both in one controller.

interface AuthContext
{
public function user(): User;
public function type(): string; // 'session' | 'token'
}
 
final class SessionAuthContext implements AuthContext
{
public function __construct(private User $user) {}
 
public function user(): User
{
return $this->user;
}
 
public function type(): string
{
return 'session';
}
}
 
final class TokenAuthContext implements AuthContext
{
public function __construct(private User $user) {}
 
public function user(): User
{
return $this->user;
}
 
public function type(): string
{
return 'token';
}
}
 
final class ChangeEmailAction
{
public function handle(AuthContext $auth, string $newEmail): void
{
// invariant: require password confirmation for session flows
if ($auth->type() === 'session') {
// e.g. middleware('password.confirm') at the route level
}
 
$auth->user()->forceFill(['email' => $newEmail])->save();
}
}
 
// Usage examples
 
// Web route/controller (session auth)
public function updateEmail(Request $request, ChangeEmailAction $action)
{
$request->validate(['email' => ['required', 'email']]);
 
$action->handle(
new SessionAuthContext($request->user()),
$request->string('email')->toString(),
);
 
return back();
}
 
// API route/controller (token auth)
public function updateEmailApi(Request $request, ChangeEmailAction $action)
{
$request->validate(['email' => ['required', 'email']]);
 
$action->handle(
new TokenAuthContext($request->user()),
$request->string('email')->toString(),
);
 
return response()->noContent();
}

References