VYPR
Critical severity9.1NVD Advisory· Published Mar 31, 2026· Updated Apr 2, 2026

CVE-2026-34532

CVE-2026-34532

Description

Parse Server is an open source backend that can be deployed to any infrastructure that can run Node.js. Prior to versions 8.6.67 and 9.7.0-alpha.11, an attacker can bypass Cloud Function validator access controls by appending "prototype.constructor" to the function name in the URL. When a Cloud Function handler is declared using the function keyword and its validator is a plain object or arrow function, the trigger store traversal resolves the handler through its own prototype chain while the validator store fails to mirror this traversal, causing all access control enforcement to be skipped. This allows unauthenticated callers to invoke Cloud Functions that are meant to be protected by validators such as requireUser, requireMaster, or custom validation logic. This issue has been patched in versions 8.6.67 and 9.7.0-alpha.11.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
parse-servernpm
>= 9.0.0, < 9.7.0-alpha.119.7.0-alpha.11
parse-servernpm
< 8.6.678.6.67

Affected products

11
  • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha5:*:*:*:node.js:*:*+ 10 more
    • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha5:*:*:*:node.js:*:*
    • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha6:*:*:*:node.js:*:*
    • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha7:*:*:*:node.js:*:*
    • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha8:*:*:*:node.js:*:*
    • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha9:*:*:*:node.js:*:*
    • cpe:2.3:a:parseplatform:parse-server:*:*:*:*:*:node.js:*:*range: <8.6.67
    • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha1:*:*:*:node.js:*:*
    • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha10:*:*:*:node.js:*:*
    • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha2:*:*:*:node.js:*:*
    • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha3:*:*:*:node.js:*:*
    • cpe:2.3:a:parseplatform:parse-server:9.7.0:alpha4:*:*:*:node.js:*:*

Patches

2
4fc48cf28f22

fix: Cloud function validator bypass via prototype chain traversal ([GHSA-vpj2-qq7w-5qq6](https://github.com/parse-community/parse-server/security/advisories/GHSA-vpj2-qq7w-5qq6)) (#10343)

2 files changed · +64 1
  • spec/vulnerabilities.spec.js+63 0 modified
    @@ -287,6 +287,69 @@ describe('Vulnerabilities', () => {
         });
       });
     
    +  describe('(GHSA-vpj2-qq7w-5qq6) Cloud function validator bypass via prototype.constructor traversal', () => {
    +    const headers = {
    +      'Content-Type': 'application/json',
    +      'X-Parse-Application-Id': 'test',
    +      'X-Parse-REST-API-Key': 'rest',
    +    };
    +
    +    it('rejects prototype.constructor traversal on function keyword handler', async () => {
    +      Parse.Cloud.define('protectedFn', function () { return 'secret'; }, { requireUser: true });
    +      const response = await request({
    +        headers,
    +        method: 'POST',
    +        url: 'http://localhost:8378/1/functions/protectedFn.prototype.constructor',
    +        body: JSON.stringify({}),
    +      }).catch(e => e);
    +      expect(response.status).toBe(400);
    +      const text = JSON.parse(response.text);
    +      expect(text.code).toBe(Parse.Error.SCRIPT_FAILED);
    +      expect(text.error).toContain('Invalid function');
    +    });
    +
    +    it('rejects prototype traversal without constructor suffix', async () => {
    +      Parse.Cloud.define('protectedFn2', function () { return 'secret'; }, { requireUser: true });
    +      const response = await request({
    +        headers,
    +        method: 'POST',
    +        url: 'http://localhost:8378/1/functions/protectedFn2.prototype',
    +        body: JSON.stringify({}),
    +      }).catch(e => e);
    +      expect(response.status).toBe(400);
    +      const text = JSON.parse(response.text);
    +      expect(text.code).toBe(Parse.Error.SCRIPT_FAILED);
    +      expect(text.error).toContain('Invalid function');
    +    });
    +
    +    it('enforces validator when calling function normally', async () => {
    +      Parse.Cloud.define('protectedFn3', function () { return 'secret'; }, { requireUser: true });
    +      const response = await request({
    +        headers,
    +        method: 'POST',
    +        url: 'http://localhost:8378/1/functions/protectedFn3',
    +        body: JSON.stringify({}),
    +      }).catch(e => e);
    +      expect(response.status).toBe(400);
    +      const text = JSON.parse(response.text);
    +      expect(text.code).toBe(Parse.Error.VALIDATION_ERROR);
    +    });
    +
    +    it('enforces requireMaster validator against prototype.constructor bypass', async () => {
    +      Parse.Cloud.define('masterOnlyFn', function () { return 'admin data'; }, { requireMaster: true });
    +      const response = await request({
    +        headers,
    +        method: 'POST',
    +        url: 'http://localhost:8378/1/functions/masterOnlyFn.prototype.constructor',
    +        body: JSON.stringify({}),
    +      }).catch(e => e);
    +      expect(response.status).toBe(400);
    +      const text = JSON.parse(response.text);
    +      expect(text.code).toBe(Parse.Error.SCRIPT_FAILED);
    +      expect(text.error).toContain('Invalid function');
    +    });
    +  });
    +
       describe('Request denylist', () => {
         describe('(GHSA-q342-9w2p-57fp) Denylist bypass via sibling nested objects', () => {
           it('denies _bsontype:Code after a sibling nested object', async () => {
    
  • src/triggers.js+1 1 modified
    @@ -113,7 +113,7 @@ function getStore(category, name, applicationId) {
           return createStore();
         }
         store = store[component];
    -    if (!store) {
    +    if (!store || Object.getPrototypeOf(store) !== null) {
           return createStore();
         }
       }
    
dc59e2726656

fix: Cloud function validator bypass via prototype chain traversal ([GHSA-vpj2-qq7w-5qq6](https://github.com/parse-community/parse-server/security/advisories/GHSA-vpj2-qq7w-5qq6)) (#10342)

2 files changed · +64 1
  • spec/vulnerabilities.spec.js+63 0 modified
    @@ -316,6 +316,69 @@ describe('Vulnerabilities', () => {
         });
       });
     
    +  describe('(GHSA-vpj2-qq7w-5qq6) Cloud function validator bypass via prototype.constructor traversal', () => {
    +    const headers = {
    +      'Content-Type': 'application/json',
    +      'X-Parse-Application-Id': 'test',
    +      'X-Parse-REST-API-Key': 'rest',
    +    };
    +
    +    it('rejects prototype.constructor traversal on function keyword handler', async () => {
    +      Parse.Cloud.define('protectedFn', function () { return 'secret'; }, { requireUser: true });
    +      const response = await request({
    +        headers,
    +        method: 'POST',
    +        url: 'http://localhost:8378/1/functions/protectedFn.prototype.constructor',
    +        body: JSON.stringify({}),
    +      }).catch(e => e);
    +      expect(response.status).toBe(400);
    +      const text = JSON.parse(response.text);
    +      expect(text.code).toBe(Parse.Error.SCRIPT_FAILED);
    +      expect(text.error).toContain('Invalid function');
    +    });
    +
    +    it('rejects prototype traversal without constructor suffix', async () => {
    +      Parse.Cloud.define('protectedFn2', function () { return 'secret'; }, { requireUser: true });
    +      const response = await request({
    +        headers,
    +        method: 'POST',
    +        url: 'http://localhost:8378/1/functions/protectedFn2.prototype',
    +        body: JSON.stringify({}),
    +      }).catch(e => e);
    +      expect(response.status).toBe(400);
    +      const text = JSON.parse(response.text);
    +      expect(text.code).toBe(Parse.Error.SCRIPT_FAILED);
    +      expect(text.error).toContain('Invalid function');
    +    });
    +
    +    it('enforces validator when calling function normally', async () => {
    +      Parse.Cloud.define('protectedFn3', function () { return 'secret'; }, { requireUser: true });
    +      const response = await request({
    +        headers,
    +        method: 'POST',
    +        url: 'http://localhost:8378/1/functions/protectedFn3',
    +        body: JSON.stringify({}),
    +      }).catch(e => e);
    +      expect(response.status).toBe(400);
    +      const text = JSON.parse(response.text);
    +      expect(text.code).toBe(Parse.Error.VALIDATION_ERROR);
    +    });
    +
    +    it('enforces requireMaster validator against prototype.constructor bypass', async () => {
    +      Parse.Cloud.define('masterOnlyFn', function () { return 'admin data'; }, { requireMaster: true });
    +      const response = await request({
    +        headers,
    +        method: 'POST',
    +        url: 'http://localhost:8378/1/functions/masterOnlyFn.prototype.constructor',
    +        body: JSON.stringify({}),
    +      }).catch(e => e);
    +      expect(response.status).toBe(400);
    +      const text = JSON.parse(response.text);
    +      expect(text.code).toBe(Parse.Error.SCRIPT_FAILED);
    +      expect(text.error).toContain('Invalid function');
    +    });
    +  });
    +
       describe('(GHSA-3v4q-4q9g-x83q) Prototype pollution via application ID in trigger store', () => {
         const prototypeProperties = ['constructor', 'toString', 'valueOf', 'hasOwnProperty', '__proto__'];
     
    
  • src/triggers.js+1 1 modified
    @@ -114,7 +114,7 @@ function getStore(category, name, applicationId) {
           return createStore();
         }
         store = store[component];
    -    if (!store) {
    +    if (!store || Object.getPrototypeOf(store) !== null) {
           return createStore();
         }
       }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.