fix(auth): throttle Fortify endpoints (registration had no limiter — signup-spam guard)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>feat/portal-design
parent
406f753311
commit
35a86c413c
|
|
@ -101,7 +101,10 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'middleware' => ['web'],
|
||||
// Throttle all Fortify endpoints (registration has no built-in limiter) to
|
||||
// blunt signup spam / CPU-exhaustion via repeated password hashing. Login
|
||||
// keeps its own stricter 'login' limiter on top.
|
||||
'middleware' => ['web', 'throttle:20,1'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -39,6 +39,21 @@ it('refuses to register with an existing customer email (account-claim guard)',
|
|||
expect(User::query()->where('email', 'claim@signup.test')->exists())->toBeFalse();
|
||||
});
|
||||
|
||||
it('throttles repeated registration attempts', function () {
|
||||
$hit429 = false;
|
||||
for ($i = 0; $i < 24; $i++) {
|
||||
$res = $this->post(route('register.store'), [
|
||||
'name' => 'S', 'email' => "spam{$i}@signup.test",
|
||||
'password' => 'password1234', 'password_confirmation' => 'password1234',
|
||||
]);
|
||||
if ($res->status() === 429) {
|
||||
$hit429 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect($hit429)->toBeTrue();
|
||||
});
|
||||
|
||||
it('rejects a mismatched password confirmation', function () {
|
||||
$this->post(route('register.store'), [
|
||||
'name' => 'X',
|
||||
|
|
|
|||
Loading…
Reference in New Issue