Summary
The /api/v1/account/forgot-password endpoint returns the full user object including PII (id, name, email, status, timestamps) in the response body instead of a generic success message. This exposes sensitive user information to unauthenticated attackers who only need to know a valid email address.
Vulnerability Details
| Field | Value |
|-------|-------|
| CWE | CWE-200: Exposure of Sensitive Information to an Unauthorized Actor |
| Affected File | packages/server/src/enterprise/services/account.service.ts (lines 517-545) |
| Endpoint | POST /api/v1/account/forgot-password |
| Authentication | None required |
| CVSS 3.1 | 3.7 (Low) |
Root Cause
In account.service.ts, the forgotPassword method returns the sanitized user object instead of a simple success acknowledgment:
public async forgotPassword(data: AccountDTO) {
// ...
const user = await this.userService.readUserByEmail(data.user.email, queryRunner)
if (!user) throw new InternalFlowiseError(StatusCodes.NOT_FOUND, UserErrorMessage.USER_NOT_FOUND)
data.user = user
// ... password reset logic ...
return sanitizeUser(data.user) // Returns user object with PII
}
The sanitizeUser function only removes sensitive authentication fields:
export function sanitizeUser(user: Partial<User>) {
delete user.credential // password hash
delete user.tempToken // reset token
delete user.tokenExpiry
return user // Still contains: id, name, email, status, createdDate, updatedDate
}
Impact
An unauthenticated attacker can:
- Harvest PII: Collect user IDs, full names, and account metadata
- Profile users: Determine account creation dates and activity patterns
- Enumerate accounts: Confirm email existence and gather associated data
- Enable further attacks: Use harvested data for social engineering or targeted phishing
<img width="1582" height="791" alt="screenshot" src="https://github.com/user-attachments/assets/9880f037-6e21-41d7-a7c8-7057c6775b50" />