Sep 2, 2026·7 min read·3 visits
A high-severity authentication bypass in Filament's app-based MFA system allows an attacker with valid primary credentials to completely skip the second-factor verification step by manipulating Livewire state parameters when recovery codes are configured.
An authentication bypass vulnerability exists in Filament's app-based (TOTP/authenticator) multi-factor authentication (MFA) system when recovery codes are enabled. This allow attackers possessing primary credentials to bypass the second-factor authentication check entirely by manipulating the Livewire state during the challenge-form validation lifecycle.
Filament is a collection of full-stack components designed for accelerated Laravel application development, frequently utilized to build administrative panels and content management portals. Within these ecosystems, secure authentication is paramount, and Filament integrates a robust multi-factor authentication (MFA) system supporting app-based Time-based One-time Password (TOTP) mechanisms.
The vulnerability, identified as CVE-2026-77567 (GHSA-52xp-w8hr-xv3c), is classified under CWE-287: Improper Authentication. It is located specifically within the validation logic of Filament's app-based MFA challenge form. This flaw allows an authenticated session in the "MFA Pending" state to bypass verification without providing a valid TOTP token or recovery code.
The attack surface is exposed directly through the Laravel Livewire lifecycle. When app-based MFA and recovery codes are enabled on a target account, the application becomes susceptible. An attacker who has acquired the target's primary username and password can exploit this conditional state evaluation mismatch to escalate their session to a fully authenticated state.
The root cause of this vulnerability lies in how the requirement constraints and dynamic visibility rules of the MFA challenge form are evaluated during the Livewire component execution cycle. The MFA form exposes two input fields: a standard TOTP input (code) and an alternative recoveryCode input.
In the vulnerable implementation, the standard TOTP code input has a dynamic required() validation rule. This rule is governed by a closure that evaluates whether the user is currently opting to use a recovery code:
->required(fn (Get $get): bool => (! $isRecoverable) || (! $get('useRecoveryCode')))If the state parameter useRecoveryCode evaluates to true, the standard TOTP code is no longer marked as required by the backend schema validator. Under normal circumstances, the recoveryCode field would then be validated as required. However, because of the way Livewire state synchronization handles dynamic visibility, if the recoveryCode field is omitted from the request payload entirely, the validator fails to enforce the required constraint on the dynamically visible recovery code field.
Because the TOTP code field is exempted from being required when useRecoveryCode is true, and the recoveryCode field's required validation is not successfully executed on the server, the form validation process completes with zero errors. The application incorrectly concludes that validation succeeded, allowing the user's session to transition into the authorized dashboard state without verifying any secondary authentication factor.
The vulnerability was resolved by amending how the requirement constraint for the standard TOTP code field is evaluated when the recovery flow is selected. The patch modifies the validation closure so that the standard OTP code remains required unless a non-blank recovery code has actually been supplied.
// Vulnerable Validation logic
->required(fn (Get $get): bool => (! $isRecoverable) || (! $get('useRecoveryCode')))
// Patched Validation logic
->required(fn (Get $get): bool => (! $isRecoverable) || (! $get('useRecoveryCode')) || blank($get('recoveryCode')))By checking blank($get('recoveryCode')), the application ensures that even if useRecoveryCode is toggled to true, the TOTP code field remains required if the recovery code input is empty. This forces at least one of the inputs to contain data.
An identical structural flaw existed in the "Disable Multi-Factor Authentication" modal, which would allow a partially authenticated user to disable MFA entirely. The following complete diff shows how the fix was implemented in both the AppAuthentication.php component and the corresponding DisableAppAuthenticationAction.php class:
File: packages/panels/src/Auth/MultiFactor/App/AppAuthentication.php
@@ -348,7 +348,7 @@ public function getChallengeFormComponents(Authenticatable $user): array
->action(fn (Set $set) => $set('useRecoveryCode', true))
->visible(fn (): bool => $isRecoverable && (! $get('useRecoveryCode'))))
->validationAttribute(__('filament-panels::auth/multi-factor/app/provider.login_form.code.validation_attribute'))
- ->required(fn (Get $get): bool => (! $isRecoverable) || (! $get('useRecoveryCode')))
+ ->required(fn (Get $get): bool => (! $isRecoverable) || (! $get('useRecoveryCode')) || blank($get('recoveryCode')))
->rule(function () use ($user): Closure {
return function (string $attribute, #[SensitiveParameter] $value, Closure $fail) use ($user): void {
if ($this->verifyCode($value, $this->getSecret($user), shouldPreventCodeReuse: true)) {
@@ -376,7 +376,6 @@ public function getChallengeFormComponents(Authenticatable $user): array
$fail(__('filament-panels::auth/multi-factor/app/provider.login_form.recovery_code.messages.invalid'));
};
})
- ->required()
->visible(fn (Get $get): bool => $isRecoverable && $get('useRecoveryCode'))
->live(onBlur: true),
];In addition to the application changes, the development team introduced regression tests within the test suite to guarantee that a blank recovery code preserves the validation requirement on the standard TOTP field.
To exploit this vulnerability, an attacker must first obtain valid primary login credentials (username and password) for a target administrative account. Once these credentials are submitted, the application redirects the session to the multi-factor authentication challenge page.
At this stage, the exploitation process involves the following sequence:
The attacker intercepts the Livewire network communication between the browser and the server using an HTTP proxy or browser developer tools.
The attacker triggers a state update call to the Livewire backend, programmatically injecting the useRecoveryCode state value:
{
"data.multiFactor.app.useRecoveryCode": true
}authenticate method) while transmitting null or blank values for both code and recoveryCode:{
"code": null,
"recoveryCode": null
}useRecoveryCode is evaluated as true, the backend relaxes the requirement check on the standard TOTP code. Simultaneously, because the recoveryCode payload parameter is omitted or null, it fails to trigger the validation exception. The session transitions to a fully authorized state, and the server returns a redirect response to the dashboard.The security impact of CVE-2026-77567 is classified as high, receiving a CVSS v3.1 score of 8.1. The attack complexity is low, and no specialized user interaction is required. However, the attacker must have privileges (low) because they require initial valid credentials to reach the second-factor authentication prompt.
If successfully exploited, this vulnerability leads to a complete bypass of the secondary authentication factor. It permits unauthorized administrative access to any vulnerable Filament installation where app-based MFA and recovery codes are enabled. This compromise allows attackers to modify system databases, extract sensitive configuration files, and execute actions on behalf of administrative users.
Because Filament is widely deployed across enterprise-facing applications, bypassing the admin-portal MFA leaves databases and cloud configurations exposed. This vulnerability significantly reduces the overall assurance level provided by the multi-factor authentication deployment.
The recommended remediation is to upgrade the Filament installation to the patched versions. Applications utilizing Filament 4.x must be upgraded to version 4.12.0 or higher. Applications running on Filament 5.x must be upgraded to version 5.7.0 or higher.
Execute the following Composer command to update the dependency:
# Upgrade for Filament 4.x applications
composer update filament/filament:"^4.12.0"
# Upgrade for Filament 5.x applications
composer update filament/filament:"^5.7.0"If patching is not immediately possible, apply one of the following configurations to eliminate the attack surface:
$isRecoverable, the conditional bypass logic path cannot be triggered.Network administrators can detect attempted exploitation by analyzing HTTP log files for Livewire payload updates where the parameter useRecoveryCode is updated to true but subsequent form submissions contain empty values for both the primary TOTP code and the recovery code.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Filament Filament | >= 4.0.0, < 4.12.0 | 4.12.0 |
Filament Filament | >= 5.0.0, < 5.7.0 | 5.7.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-287 (Improper Authentication) |
| Attack Vector | Network |
| CVSS v3.1 | 8.1 |
| EPSS Score | 0.00304 |
| EPSS Percentile | 22.61% |
| Exploit Status | PoC (Proof-of-Concept) |
| KEV Status | Not Listed |
The software does not perform or incorrectly performs an authentication step, allowing attackers to access restricted data or execute actions without identity verification.
An algorithmic complexity vulnerability in the pypdf library before version 6.16.1 allows remote or local attackers to cause an application denial of service. The flaw is triggered via maliciously crafted PDF documents that utilize either deeply nested outlines or exponential Directed Acyclic Graph (DAG) structures in Form XObjects.
An authentication oracle vulnerability exists in Filament before 4.12.5 and 5.7.5. The application initiates MFA challenge workflows prior to verifying user authorization policies, allowing unauthenticated attackers to validate guessed credentials.
A multi-factor authentication bypass vulnerability exists in Filament (Laravel full-stack framework panels) due to improper time-step tracking of Time-Based One-Time Password (TOTP) codes. By submitting valid TOTP codes from an older time window within the drift allowance, an attacker with a user's password can bypass the single-use MFA guarantee and obtain unauthorized account access.
CVE-2026-19418 is a high-severity origin validation vulnerability in TYPO3 CMS that enables Cross-Site Request Forgery (CSRF) and access control bypasses. Due to architectural consolidation of entry points in version 13.0, the core ReferrerEnforcer fails to isolate backend endpoints from the frontend, allowing an attacker with frontend script execution capabilities to perform unauthorized administrative actions.
CVE-2026-84304 is a high-severity uncontrolled resource consumption vulnerability in gRPC-Go, the Go implementation of the gRPC framework. The issue stems from a memory amplification flaw inside the HTTP/2 DATA frame processing subsystem. Remote, unauthenticated attackers can exploit this vulnerability by sending a high volume of heavily fragmented, tiny DATA frames within multiplexed concurrent streams. This causes gRPC-Go servers to allocate excessive internal metadata structures on the Go heap, leading to severe heap memory amplification, intense garbage collection thrashing, and process termination due to Out-of-Memory (OOM) conditions.
CVE-2026-79675 is a critical command injection vulnerability in NLTK versions prior to 3.10.3 that permits remote attackers to execute arbitrary code on the hosting system. This vulnerability stems from an incomplete mitigation of a previous vulnerability, CVE-2026-12841. While NLTK verified global JVM options configured through the library's setup routines, it failed to perform equivalent safety checks on options provided during per-call invocations of Stanford NLP Java wrappers. Attackers controlling these parameters can pass dangerous Java configuration options to the system shell, bypassing security boundaries to spawn interactive processes or load untrusted Java archives.