refactor(auth): upgrade email verification hash to sha256

Move the email-verification URL hash from sha1 to sha256 and verify it
directly in the controller using hash_equals, instead of going through
Laravel's EmailVerificationRequest (which only compares against sha1).
The signed URL still carries the authoritative HMAC; the hash upgrade
keeps the identity binding aligned with modern hashing guidance.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-04-20 12:09:17 +02:00
parent 9b37a1a7eb
commit 49b5472961
3 changed files with 97 additions and 4 deletions
+23 -3
View File
@@ -6,8 +6,8 @@ use App\Events\TestEvent;
use App\Models\TeamInvitation;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Verified;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Auth\EmailVerificationRequest;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
@@ -39,9 +39,29 @@ class Controller extends BaseController
return view('auth.verify-email');
}
public function email_verify(EmailVerificationRequest $request)
public function email_verify(Request $request)
{
$request->fulfill();
if (! $request->hasValidSignature()) {
abort(403);
}
$user = auth()->user();
if (! $user) {
abort(403);
}
if (! hash_equals((string) $request->route('id'), (string) $user->getKey())) {
abort(403);
}
if (! hash_equals((string) $request->route('hash'), hash('sha256', $user->getEmailForVerification()))) {
abort(403);
}
if (! $user->hasVerifiedEmail()) {
$user->markEmailAsVerified();
event(new Verified($user));
}
return redirect(RouteServiceProvider::HOME);
}