Security: 2FA-Bypass beheben & Login-Pfade konsolidieren
Befund (Review 16.06.): Der Volt-Login machte direkt Auth::attempt() und umging Fortifys 2FA-Pipeline (2FA-Bypass); zusätzlich existierte der Fortify-POST /login parallel mit schwächeren Post-Login-Regeln. Fix (Volt-nativ): - Volt-Login prüft Credentials ohne sofortiges Login; bei aktivem 2FA wird der Session-Vertrag login.id/login.remember gesetzt und auf eine neue Volt- 2FA-Challenge-Seite (/two-factor-challenge) geleitet, die an Fortifys bestehenden Controller postet (TOTP + Recovery-Code). - Gemeinsame Post-Login-Logik in App\Support\LoginRedirect (rollengerechtes Home + 403-sicherer intended-Redirect), genutzt von Volt-Login UND Response. - RoleAwareLoginResponse implementiert jetzt LoginResponse UND TwoFactorLoginResponse und erzwingt einheitlich: unverifiziert → Notice, verifiziert-inaktiv → Logout+Fehler, sonst 403-sicherer Redirect. Damit ist auch der direkte Fortify-POST-Pfad gehärtet. Tests: 2FA-Übergabe, Challenge-Guard, voller TOTP-Flow, Fortify-POST blockt inaktive User und hält Customer aus dem Admin-Bereich. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d98d297524
commit
f4ca452c6b
8 changed files with 295 additions and 81 deletions
79
resources/views/livewire/auth/two-factor-challenge.blade.php
Normal file
79
resources/views/livewire/auth/two-factor-challenge.blade.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Volt\Component;
|
||||
|
||||
new #[Layout('components.layouts.auth.pressekonto', ['heading' => 'Zwei-Faktor-Bestätigung', 'eyebrow' => 'Sicherheitsprüfung', 'showFromBanner' => false])] class extends Component {
|
||||
public function mount(): void
|
||||
{
|
||||
// Ohne laufende Challenge (login.id aus dem ersten Schritt) hat die Seite
|
||||
// keinen Kontext – zurück zum Login.
|
||||
if (! session()->has('login.id')) {
|
||||
$this->redirect(route('login'), navigate: false);
|
||||
}
|
||||
}
|
||||
}; ?>
|
||||
|
||||
<div x-data="{ recovery: false }">
|
||||
@if ($errors->any())
|
||||
<div class="field-status mb-4" role="alert">
|
||||
{{ $errors->first() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<p class="text-[13.5px] text-ink-2 leading-[1.65] !-mt-2 mb-6">
|
||||
<span x-show="! recovery">
|
||||
Geben Sie den 6-stelligen Code aus Ihrer Authenticator-App ein.
|
||||
</span>
|
||||
<span x-show="recovery" x-cloak>
|
||||
Geben Sie einen Ihrer Wiederherstellungs-Codes ein.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
{{-- Echter POST an Fortifys 2FA-Challenge-Controller (verifiziert gegen die
|
||||
login.id aus der Session und loggt bei Erfolg ein). --}}
|
||||
<form method="POST" action="/two-factor-challenge" class="space-y-[18px]">
|
||||
@csrf
|
||||
|
||||
<div x-show="! recovery">
|
||||
<label class="field-label" for="code">Authentifizierungs-Code</label>
|
||||
<input
|
||||
id="code"
|
||||
name="code"
|
||||
type="text"
|
||||
inputmode="numeric"
|
||||
autocomplete="one-time-code"
|
||||
class="field-input"
|
||||
placeholder="123456"
|
||||
x-bind:disabled="recovery"
|
||||
x-ref="code"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div x-show="recovery" x-cloak>
|
||||
<label class="field-label" for="recovery_code">Wiederherstellungs-Code</label>
|
||||
<input
|
||||
id="recovery_code"
|
||||
name="recovery_code"
|
||||
type="text"
|
||||
autocomplete="one-time-code"
|
||||
class="field-input"
|
||||
placeholder="xxxxxxxx-xxxxxxxx"
|
||||
x-bind:disabled="! recovery"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="auth-btn-primary !mt-[18px]">
|
||||
Bestätigen
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="auth-btn-outline !mt-0"
|
||||
x-on:click="recovery = ! recovery; $nextTick(() => (recovery ? document.getElementById('recovery_code') : $refs.code)?.focus())"
|
||||
>
|
||||
<span x-show="! recovery">Wiederherstellungs-Code verwenden</span>
|
||||
<span x-show="recovery" x-cloak>Code aus App verwenden</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue