Skip to content

Commit fd44775

Browse files
Support HMAC password hash format from Laravel 12.45.0+ (#578)
Laravel Framework v12.45.0 (PR laravel/framework#58107) changed how password hashes are stored in sessions - they're now stored as HMACs instead of raw hashes for improved security. This updates Sanctum's AuthenticateSession middleware to: 1. Use hashPasswordForCookie() when storing the password hash (if available) 2. Add validatePasswordHash() that tries HMAC format first, falls back to raw hash comparison for backward compatibility This ensures compatibility when both $middleware->authenticateSessions() and Sanctum stateful auth are enabled together. Fixes #577
1 parent fe4633e commit fd44775

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

src/Http/Middleware/AuthenticateSession.php

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,11 @@ public function handle(Request $request, Closure $next): Response
5050
$shouldLogout = $guards->filter(
5151
fn ($guard, $driver) => $request->session()->has('password_hash_'.$driver)
5252
)->filter(
53-
fn ($guard, $driver) => $request->session()->get('password_hash_'.$driver) !==
54-
$request->user()->getAuthPassword()
53+
fn ($guard, $driver) => ! $this->validatePasswordHash(
54+
$guard,
55+
$request->user()->getAuthPassword(),
56+
$request->session()->get('password_hash_'.$driver)
57+
)
5558
);
5659

5760
if ($shouldLogout->isNotEmpty()) {
@@ -94,8 +97,33 @@ protected function getFirstGuardWithUser(Collection $guards)
9497
*/
9598
protected function storePasswordHashInSession($request, string $guard)
9699
{
100+
$guardInstance = $this->auth->guard($guard);
101+
97102
$request->session()->put([
98-
"password_hash_{$guard}" => $this->auth->guard($guard)->user()->getAuthPassword(),
103+
"password_hash_{$guard}" => method_exists($guardInstance, 'hashPasswordForCookie')
104+
? $guardInstance->hashPasswordForCookie($guardInstance->user()->getAuthPassword())
105+
: $guardInstance->user()->getAuthPassword(),
99106
]);
100107
}
108+
109+
/**
110+
* Validate the password hash against the stored value.
111+
*
112+
* @param \Illuminate\Auth\SessionGuard $guard
113+
* @param string $passwordHash
114+
* @param string $storedValue
115+
* @return bool
116+
*/
117+
protected function validatePasswordHash(SessionGuard $guard, string $passwordHash, string $storedValue): bool
118+
{
119+
// Try new HMAC format first (Laravel 12.45.0+)...
120+
if (method_exists($guard, 'hashPasswordForCookie')) {
121+
if (hash_equals($guard->hashPasswordForCookie($passwordHash), $storedValue)) {
122+
return true;
123+
}
124+
}
125+
126+
// Fall back to raw password hash format for backward compatibility...
127+
return hash_equals($passwordHash, $storedValue);
128+
}
101129
}

0 commit comments

Comments
 (0)