# Flowise: resetPassword Authentication Bypass Vulnerability

Flowise resetPassword compares submitted token against a null/empty stored tempToken, letting unauthenticated attackers reset passwords of recently created accounts.

- Payout: Research
- Severity: high
- Program: Flowise
- Found by: zdi-disclosures
- Disclosed: 2026-04-16
- CVE: CVE-2026-41276
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-f6hc-c5jr-878p
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-f6hc-c5jr-878p
- Tags: area:web domain:api domain:web impact:ato impact:privesc kind:research platform:ghsa sev:high tech:nodejs technique:source-review vuln:account-takeover vuln:auth-bypass

**Target:** Express API endpoint /api/v1/account/reset-password
**Root cause:** resetPassword() compares the supplied tempToken to the stored user.tempToken without verifying a token was ever generated; the stored value defaults to null (or empty string after a prior reset), so a null/empty submission matches.
**Steps:**
1. Install vulnerable version: `npm install flowise@3.0.12` and `npx flowise start`
2. Identify a target account created within the last 15 minutes (or PASSWORD_RESET_TOKEN_EXPIRY_IN_MINUTES)
3. POST to `/api/v1/account/reset-password` with JSON body containing the victim email, `tempToken: null`, and new password `TMSR1234!`
4. If that fails, resend the same request with `tempToken: ""` (empty string)
5. Log in with the new password to confirm account takeover
**How found:** Code review of AccountService.resetPassword revealed the token comparison lacked a check that a token had actually been issued, and that the stored tempToken defaults to null/empty and tokenExpiry defaults to creation time plus expiry window.
**Exploitation:** Unauthenticated attacker knowing a recently created account's email submits a reset-password request with a null or empty tempToken and a chosen password; the token equality check passes and the expiry check passes because tokenExpiry defaults to account creation + 15 minutes, so the password is overwritten and all sessions invalidated.
**Insight:** When auditing password-reset flows, check the default/uninitialized state of the stored token and expiry fields: a null==null or ''=='' comparison plus a creation-time-derived expiry lets an attacker reset any freshly created account without ever requesting a token.

## Proof of concept (copied exactly from the original report)

**POST reset-password with null/empty token**

```
By default, the poc will first send a POST request to the "/api/v1/account/reset-password" endpoint of the target server containing a JSON body with a null reset token and the password "TMSR1234!" for the user specified by the USER argument. If the request doesn't successfully change the user's password, the same request will be sent again with the reset token value set to the empty string. Upon successful exploitation, the user's password will be changed to "TMSR1234!".
```

