Jun 19, 2026·8 min read·2 visits
Parse Server improperly falls back to returning raw, unsanitized database rows containing plaintext MFA TOTP secrets and recovery codes when user re-fetch queries are blocked by restricted Class-Level Permissions, allowing attackers with primary credentials to bypass second-factor controls.
CVE-2026-53725 is a critical sensitive information disclosure vulnerability in Parse Server (versions 9.8.0 to < 9.9.1-alpha.5). When Multi-Factor Authentication (MFA) is enabled and standard read permissions on the _User class are restricted via Class-Level Permissions (CLPs), the /login and /verifyPassword endpoints improperly fall back to returning the raw database row upon a failed mock re-fetch request. This behavior leaks plaintext MFA TOTP secrets, recovery codes, and fields designated as protected, enabling attackers with compromised user passwords to bypass multi-factor authentication controls entirely.
Parse Server is a highly customizable, open-source backend framework designed to manage application data, authentication, and user sessions. To maintain separation of concerns and protect sensitive properties, Parse Server relies on Class-Level Permissions (CLPs) and Access Control Lists (ACLs) to validate read and write operations. The attack surface of this vulnerability lies directly within the application's core user-handling endpoints, specifically the /login and /verifyPassword routes.
When administrators configure restrictive security policies, a common practice is to deny the get operation on the _User class. This restriction ensures that users cannot query arbitrary attributes of other user profiles. However, this specific combination of a restrictive CLP and enabled Multi-Factor Authentication (MFA) triggers an administrative logical failure during authentication, classified as CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor).
If standard retrieve access is denied on the _User class, the server fails to safely sanitize the session payload. Rather than denying the request or generating an access-control exception, the system falls back to providing the fully detailed, unsanitized raw database record. This behavior exposes critical internal fields, including raw MFA Time-Based One-Time Password (TOTP) keys and corresponding recovery secrets, directly to the client.
The core of the vulnerability lies in how Parse Server processes authenticated requests within src/Routers/UsersRouter.js. When a user attempts to authenticate via the /login or /verifyPassword endpoints, Parse Server first queries the database using master-level database credentials. This query retrieves the complete, raw user object containing all stored properties, including passwords, internal metadata, and the critical authData column which holds MFA secrets.
To prevent leaking internal properties or restricted data to the client, Parse Server processes the raw user object through an internal sanitization pipeline. This pipeline executes a mock 're-fetch' query (this.restFind) using the restricted access context of the calling user. The goal of the re-fetch is to apply Class-Level Permissions (CLPs), exclude fields marked in protectedFields, and trigger custom afterFind triggers or authentication-adapter sanitizers. Normally, these sanitizers replace raw MFA parameters with a generic status indicator.
In vulnerable versions of Parse Server, this mock re-fetch is enclosed in a try-catch block. If the Class-Level Permissions explicitly deny the get action on the _User class (get: {}), or if the user's ACL does not permit the read operation, the re-fetch query throws an access-denied error. Instead of propagating this error or returning an empty response, the server catches the exception and evaluates a dangerous fallback condition: if no filtered user object is returned from the query, the server sets filteredUser = user, which represents the raw, unsanitized database row. This completely bypasses the sanitization pipeline and exposes all protected fields.
The vulnerable implementation in src/Routers/UsersRouter.js handled the re-fetch failure as a silent error, assuming it occurred only for legacy users without ACLs. This assumption overlooked cases where the query failed due to restrictive CLPs. The original code block was implemented as follows:
try {
filteredUserResponse = await this.restFind(...);
filteredUser = filteredUserResponse.results?.[0];
} catch {
// re-fetch may fail for legacy users without ACL; fall through
}
if (!filteredUser) {
filteredUser = user; // Vulnerable fallback returning raw database row
}The patch introduced in Pull Request #10492 restructures this fallback logic to ensure that regular, non-administrative clients do not receive raw database structures. The revised code explicitly checks the privilege level of the calling request before determining what representation of the user object to return. If the caller holds master or maintenance credentials, the system continues to return the raw object as they bypass CLPs and field-protection rules. For all other authentication contexts, if the mock re-fetch fails, the server constructs a minimal response containing only the identifier (objectId), completely omitting any other attributes:
try {
filteredUserResponse = await this.restFind(...);
filteredUser = filteredUserResponse.results?.[0];
} catch {
// The re-fetch enforces `_User` `get` CLP and may be denied by access
// control (e.g. CLP `get: {}` or an ACL that excludes the caller).
// Handled below; never fall back to the raw row.
}
if (!filteredUser) {
// Master/maintenance callers bypass CLP, protectedFields, and authData
// afterFind, so for them an empty re-fetch is a genuine not-found edge, not
// an access-control denial; they are entitled to the full row. For every
// other caller, an empty/denied re-fetch means access control withheld the
// record, so disclose only the identity — never the raw row, which would
// leak fields hidden by `protectedFields` and raw `authData` (e.g. MFA
// secrets and recovery codes) that the sanitizing re-fetch would remove.
// The session token is still attached below so login succeeds.
filteredUser =
req.auth.isMaster || req.auth.isMaintenance ? user : { objectId: user.objectId };
}This remediation is highly complete. It establishes a fail-secure posture: rather than defaulting to maximum data exposure when a validation or security check fails, the framework defaults to minimum data exposure. Because the sessionToken is still attached to this minimal object, the core authentication flow succeeds without compromising the application's underlying security boundaries.
Exploitation of CVE-2026-53725 requires the attacker to have already compromised or obtained the primary authentication credentials of the target user. Consequently, this vulnerability is leveraged for multi-factor authentication bypass rather than initial entry. The process begins with the attacker issuing an HTTP POST request to the /verifyPassword endpoint containing the victim's valid username and password.
When the mock re-fetch fails due to the restricted CLP, the server executes the vulnerable exception block and responds with an HTTP 200 containing the raw user database row. This JSON payload includes the nested authData.mfa block, disclosing the plaintext TOTP secret key (secret) and the backup codes (recovery).
{
"objectId": "aBcDeFg123",
"username": "victim_user",
"phone": "555-1234",
"authData": {
"mfa": {
"secret": "MJSXG5DPEBPTWYLN",
"recovery": ["1234-5678", "9876-5432"]
}
}
}Upon extracting the raw base32 TOTP secret, the attacker inputs this seed into any standard authenticator utility. The utility generates valid one-time security codes matching the victim's account configuration. The attacker can then complete the full login sequence, successfully providing both the primary password and the secondary multi-factor code, thereby entirely undermining the multi-factor authentication mechanism.
The security impact of CVE-2026-53725 is categorized as Medium with a CVSS 4.0 score of 5.9. Although the rating is moderate due to the prerequisite of possessing the user's primary credentials, the actual security impact on compromised accounts is high. Multi-factor authentication is implemented specifically to protect user accounts in the event of primary credential theft. By exposing the underlying shared TOTP secrets and recovery codes, this vulnerability nullifies the security guarantees provided by multi-factor authentication controls.
The CVSS vector CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N highlights key operational elements of this flaw. The attack vector is Network (AV:N), meaning it can be exploited remotely over HTTP without requiring physical or local access. The attack complexity is Low (AC:L) because triggering the flaw involves a standard API request. However, the Attack Requirements metric is evaluated as Present (AT:P), as the flaw only manifests when both MFA is enabled and the _User CLP restricts standard get operations.
From a data exposure perspective, the Confidentiality impact (VC) is High. In addition to MFA credentials, the leak exposes fields defined under protectedFields (such as email addresses, phone numbers, or administrative flags) that are supposed to be protected from disclosure. This can lead to broader privacy violations and downstream exploitation, such as social engineering or targeted phishing campaigns using leaked contact information.
Because there is no official public signature for this vulnerability, defensive engineering teams can implement a custom detection template to scan their internal environments. The following template detects if a mock authenticated request returns raw database rows rather than sanitized object profiles:
id: cve-2026-53725-parse-server-leak
info:
name: Parse Server MFA Secrets Leak
author: defensive-engineering
severity: medium
description: |
Verifies if the Parse Server instance exposes raw MFA secrets in /verifyPassword
when the _User get CLP permission is restricted.
reference:
- https://github.com/parse-community/parse-server/security/advisories/GHSA-75v4-m273-5j49
- https://github.com/parse-community/parse-server/pull/10492
classification:
cwe-id: CWE-200
http:
- method: POST
path:
- "{{BaseURL}}/parse/verifyPassword"
headers:
X-Parse-Application-Id: "{{app_id}}"
X-Parse-REST-API-Key: "{{rest_key}}"
Content-Type: "application/json"
body: |
{
"username": "{{test_user}}",
"password": "{{test_password}}"
}
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
part: body
words:
- '"objectId":'
- '"authData":'
- '"secret":'
condition: andCVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
parse-server parse-community | >= 9.8.0, < 9.9.1-alpha.5 | 9.9.1-alpha.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-200: Exposure of Sensitive Information to an Unauthorized Actor |
| Attack Vector | Network (AV:N) |
| CVSS v4.0 Score | 5.9 (Medium) |
| EPSS Score | 0.00251 (Percentile: 16.20%) |
| Impact | Full multi-factor authentication bypass and sensitive profile information leak |
| Exploit Status | None (No public exploit code or active exploitation reported) |
| KEV Status | Not listed in CISA KEV catalog |
The product exposes sensitive information to an actor who is not authorized to have access to that information.
The http4k-security-digest module within the http4k library fails to validate HTTP Digest Access Authentication nonces by default. Due to an always-true nonce verifier lambda implementation, applications using default configurations do not enforce session freshness or uniqueness. This design flaw allows remote attackers to perform replay attacks, gaining unauthorized access to protected endpoints by intercepting and retransmitting valid authorization headers.
CVE-2026-11769 is a directory traversal vulnerability affecting the Grafana Operator before version 5.24.0. An authenticated attacker with basic namespace privileges can deploy a crafted GrafanaDashboard or GrafanaLibraryPanel custom resource to read sensitive local files. This enables the extraction of the service account token of the operator manager, resulting in cluster-wide privilege escalation.
Parse Server prior to versions 8.6.80 and 9.9.1-alpha.6 contains an authorization bypass vulnerability in its relation query handling. A database query utilizing the `$relatedTo` operator can read the membership details of a Relation field even when that field is hidden via `protectedFields` or restricted by object-level Access Control Lists (ACLs).
A critical SQL injection vulnerability was discovered in TypeORM's UpdateQueryBuilder and SoftDeleteQueryBuilder when targeting MySQL and MariaDB backends. The flaw allows unauthenticated remote attackers to execute arbitrary SQL commands because input validation was bypassed on certain method signatures. The initial patch was incomplete, leaving a bypass open, which was resolved in the final security update.
Hugo versions v0.123.0 through v0.163.0 are vulnerable to a directory confinement bypass. A regression in the virtual filesystem layer causes symbolic links to be followed during template execution, allowing templates to read arbitrary host files.
A critical missing authorization vulnerability exists in the API Pages Controller of Alchemy CMS. An unauthenticated remote attacker can exploit the 'nested' action to retrieve the entire nested page tree. Furthermore, by appending the query parameter '?elements=true', the attacker can extract sensitive content from draft, unpublished, and restricted pages, bypassing all access controls.