CVE-2025-59934 Overview
CVE-2025-59934 is a critical authentication bypass vulnerability in Formbricks, an open source Qualtrics alternative. The vulnerability stems from a token validation routine that only decodes JWTs using jwt.decode without verifying their cryptographic signatures. Both the email verification token login path and the password reset server action use the same vulnerable validator, which fails to check the token's signature, expiration, issuer, or audience claims.
If an attacker learns the victim's actual user.id, they can craft an arbitrary JWT with an alg: "none" header and use it to authenticate as the victim or reset the victim's password. This is a classic JWT algorithm confusion vulnerability that allows complete account takeover.
Critical Impact
Attackers can forge authentication tokens to gain unauthorized access to any user account, enabling complete account takeover including password reset capabilities without valid credentials.
Affected Products
- Formbricks versions prior to 4.0.1
Discovery Timeline
- 2025-09-26 - CVE-2025-59934 published to NVD
- 2025-09-29 - Last updated in NVD database
Technical Details for CVE-2025-59934
Vulnerability Analysis
This vulnerability represents a fundamental flaw in JWT token handling where the application decodes tokens without verifying their authenticity. The vulnerable code in apps/web/lib/jwt.ts uses jwt.decode() instead of jwt.verify(), completely bypassing signature validation.
The JWT specification allows the alg header to specify the algorithm used to sign the token. When an application accepts the alg: "none" algorithm without proper validation, attackers can create unsigned tokens that the application incorrectly treats as valid. This vulnerability affects both the email verification flow and password reset functionality, making it particularly dangerous as it provides multiple attack paths to account compromise.
Root Cause
The root cause is the use of jwt.decode() for token validation instead of jwt.verify(). The jwt.decode() function only parses the JWT payload without checking the signature, while jwt.verify() performs complete cryptographic signature verification against the expected secret or public key. Additionally, the validator does not check critical claims such as token expiration (exp), issuer (iss), or audience (aud), further weakening the authentication mechanism.
Attack Vector
An attacker who obtains or guesses a valid user.id can exploit this vulnerability through the following attack flow:
- Craft a malicious JWT with alg: "none" in the header
- Set the payload with the target user's user.id
- Submit the forged token to the email verification or password reset endpoint
- Gain authenticated access or reset the victim's password
The vulnerability is network-accessible and requires no privileges, though the attacker needs to obtain a valid user.id to craft the malicious token.
+import { render } from "@react-email/render";
+import { createTransport } from "nodemailer";
+import type SMTPTransport from "nodemailer/lib/smtp-transport";
+import { logger } from "@formbricks/logger";
+import type { TLinkSurveyEmailData } from "@formbricks/types/email";
+import { InvalidInputError } from "@formbricks/types/errors";
+import type { TResponse } from "@formbricks/types/responses";
+import type { TSurvey } from "@formbricks/types/surveys/types";
+import { TUserEmail, TUserLocale } from "@formbricks/types/user";
import {
DEBUG,
MAIL_FROM,
Source: GitHub Commit eb1349f
Detection Methods for CVE-2025-59934
Indicators of Compromise
- JWT tokens submitted to authentication endpoints with alg: "none" or alg: "None" in the header
- Password reset requests with abnormal token structures lacking valid signatures
- Multiple authentication attempts using tokens with identical payloads but varying headers
- Successful authentications where the JWT signature portion is empty or contains only base64 padding
Detection Strategies
- Implement logging for JWT validation failures, specifically capturing algorithm mismatches
- Monitor authentication endpoints for requests containing tokens with empty signature segments
- Deploy Web Application Firewall (WAF) rules to detect and block tokens with alg: "none" headers
- Alert on password reset completions where the associated token exhibits suspicious characteristics
Monitoring Recommendations
- Enable detailed audit logging for all authentication and password reset operations
- Monitor for account takeover indicators such as password changes followed by immediate profile modifications
- Track failed and successful authentication attempts per user to identify anomalous patterns
- Review logs for requests to /api/auth/verify-email and password reset endpoints with malformed JWTs
How to Mitigate CVE-2025-59934
Immediate Actions Required
- Upgrade Formbricks to version 4.0.1 or later immediately
- Review authentication logs for evidence of exploitation attempts using unsigned or weakly signed tokens
- Force password resets for any accounts showing suspicious activity
- Audit recent account changes, particularly password modifications, for signs of compromise
Patch Information
The vulnerability has been patched in Formbricks version 4.0.1. The fix enhances JWT handling with improved encryption and decryption logic, ensuring proper signature verification is performed on all tokens. The security patch was addressed through Pull Request #6596 and committed as eb1349f. For complete technical details, refer to the GitHub Security Advisory GHSA-7229.
Workarounds
- If immediate patching is not possible, implement a reverse proxy or WAF rule to reject requests containing JWTs with alg: "none" headers
- Restrict access to email verification and password reset endpoints to known IP ranges where feasible
- Consider temporarily disabling self-service password reset functionality until the patch can be applied
- Implement additional authentication factors for sensitive operations as a defense-in-depth measure
# Example: Block alg:none JWTs at reverse proxy (nginx)
# Add to location block handling authentication endpoints
if ($http_authorization ~* "eyJ[A-Za-z0-9_-]*Ijoibm9uZSI") {
return 403;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

