Every CVE Search/ Get API key

CVE-2026-39857

Information Disclosure via `choices`/`counts` Query Parameters Bypassing publicApiProjection Field Restrictions

5.3 MediumFix available

ApostropheCMS is an open-source Node.js content management system. Versions 4.28.0 and prior contain an authorization bypass vulnerability in the choices and counts query parameters of the REST API, where these query builders execute MongoDB distinct() operations that bypass the publicApiProjection restrictions intended to limit which fields are exposed publicly. The choices and counts parameters are processed via applyBuildersSafely before the projection is applied, and MongoDB's distinct operation does not respect projections, returning all distinct values directly. The results are returned in the API response without any filtering against publicApiProjection or removeForbiddenFields. An unauthenticated attacker can extract all distinct field values for any schema field type that has a registered query builder, including string, integer, float, select, boolean, date, slug, and relationship fields. Fields protected with viewPermission are similarly exposed, and the counts variant additionally reveals how many documents have each distinct value. Both the piece-type and page REST APIs are affected. This issue has been fixed in version 4.29.0.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
Low
Integrity
None
Availability
None

Exploit likelihood

0.43%Up 0.4 points since Apr 16, 2026
90%50%10%1%

What each source reports

CVE List Score used 5.3

Information Disclosure via `choices`/`counts` Query Parameters Bypassing publicApiProjection Field Restrictions

ApostropheCMS is an open-source Node.js content management system. Versions 4.28.0 and prior contain an authorization bypass vulnerability in the choices and counts query parameters of the REST API, where these query builders execute MongoDB distinct() operations that bypass the publicApiProjection restrictions intended to limit which fields are exposed publicly. The choices and counts parameters are processed via applyBuildersSafely before the projection is applied, and MongoDB's distinct operation does not respect projections, returning all distinct values directly. The results are returned in the API response without any filtering against publicApiProjection or removeForbiddenFields. An unauthenticated attacker can extract all distinct field values for any schema field type that has a registered query builder, including string, integer, float, select, boolean, date, slug, and relationship fields. Fields protected with viewPermission are similarly exposed, and the counts variant additionally reveals how many documents have each distinct value. Both the piece-type and page REST APIs are affected. This issue has been fixed in version 4.29.0.

Record
CVE-2026-39857
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Weakness
CWE-200
Updated
2026-11-02
EUVDEUVD-2026-23108 5.3

ApostropheCMS is an open-source Node.js content management system. Versions 4.28.0 and prior contain an authorization bypass vulnerability in the choices and counts query parameters of the REST API, where these query builders execute MongoDB distinct() operations that bypass the publicApiProjection restrictions intended to limit which fields are exposed publicly. The choices and counts parameters are processed via applyBuildersSafely before the projection is applied, and MongoDB's distinct operation does not respect projections, returning all distinct values directly. The results are returned in the API response without any filtering against publicApiProjection or removeForbiddenFields. An unauthenticated attacker can extract all distinct field values for any schema field type that has a registered query builder, including string, integer, float, select, boolean, date, slug, and relationship fields. Fields protected with viewPermission are similarly exposed, and the counts variant additionally reveals how many documents have each distinct value. Both the piece-type and page REST APIs are affected. This issue has been fixed in version 4.29.0.

Record
EUVD-2026-23108
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-c276-fj82-f2pq 5.3

ApostropheCMS: Information Disclosure via choices/counts Query Parameters Bypassing publicApiProjection Field Restrictions

Summary

The choices and counts query parameters in the Apostrophe CMS REST API allow unauthenticated users to extract distinct field values for any schema field that has a registered query builder, completely bypassing publicApiProjection restrictions that are intended to limit which fields are exposed publicly. Fields protected by viewPermission are similarly exposed.

Details

When a piece type configures publicApiProjection to enable public API access while restricting visible fields, the restriction is enforced via a MongoDB projection on the main query (piece-type/index.js:1130-1134). However, the choices and counts query builders bypass this protection through a separate code path.

The vulnerable flow:

  1. getRestQuery at piece-type/index.js:1120 calls applyBuildersSafely(req.query) (line 1122), which processes query parameters including choices and counts since both have launder methods (doc-type/index.js:2627-2628 and 2675-2676).

  2. The publicApiProjection is applied afterward (line 1130-1134) as a MongoDB projection on the main query.

  3. During query execution, the choices builder's after handler (doc-type/index.js:2636-2668) iterates over requested field names. The only validation is:

    • The field has a registered builder (_.has(query.builders, filter) at line 2651)
    • The builder has a launder method (line 2656)

    All schema field types (string, integer, float, select, boolean, date, slug, relationship) register query builders with launder methods via addQueryBuilder in addFieldTypes.js.

  4. toChoices (line 2661) calls the field's choices function, which typically calls sortedDistinct → toDistinct. The toDistinct method (doc-type/index.js:2811) executes db.distinct(property, criteria) — a MongoDB operation that returns all distinct values for the given property matching the criteria. MongoDB's distinct operation does not respect projections; it operates directly on the specified field regardless of any projection set on the query.

  5. The results are stored via query.set('choicesResults', choices) (line 2666) and returned directly in the API response at piece-type/index.js:292-296 without any filtering against publicApiProjection or removeForbiddenFields.

The same bypass applies to viewPermission-protected fields: removeForbiddenFields (doc-type/index.js:1585-1611) only processes document results from toArray(), not the separate choices/counts data.

The page REST API has the same issue at page/index.js:371-376.

PoC

# Prerequisites:
# - An Apostrophe 4.x instance with a piece type configured with publicApiProjection
# - Example: an 'article' piece type with:
#   publicApiProjection: { title: 1, slug: 1, _url: 1 }
#   and additional schema fields like 'status' (select), 'priority' (integer),
#   or 'internalNotes' (string) NOT in the projection

# 1. Verify normal API access only returns projected fields
curl -s 'http://localhost:3000/api/v1/article' | python3 -m json.tool
# Response results contain only: title, slug, _url (as configured)

# 2. Extract distinct values of a non-projected field via choices
curl -s 'http://localhost:3000/api/v1/article?choices=status' | python3 -m json.tool
# Response includes:
# "choices": {"status": [{"value": "draft", "label": "draft"}, {"value": "published", "label": "published"}, ...]}

# 3. Extract distinct values with document counts via counts
curl -s 'http://localhost:3000/api/v1/article?counts=priority' | python3 -m json.tool
# Response includes:
# "counts": {"priority": [{"value": 1, "label": "1", "count": 15}, {"value": 2, "label": "2", "count": 8}, ...]}

# 4. Multiple fields can be extracted at once
curl -s 'http://localhost:3000/api/v1/article?choices=status,priority,internalNotes'

Impact

  • Distinct field values leaked: An unauthenticated attacker can extract all distinct values of any schema field on any piece type that has publicApiProjection…
Record
GHSA-c276-fj82-f2pq
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Weakness
CWE-200
Updated
2026-11-02
NVD 5.3

ApostropheCMS is an open-source Node.js content management system. Versions 4.28.0 and prior contain an authorization bypass vulnerability in the choices and counts query parameters of the REST API, where these query builders execute MongoDB distinct() operations that bypass the publicApiProjection restrictions intended to limit which fields are exposed publicly. The choices and counts parameters are processed via applyBuildersSafely before the projection is applied, and MongoDB's distinct operation does not respect projections, returning all distinct values directly. The results are returned in the API response without any filtering against publicApiProjection or removeForbiddenFields. An unauthenticated attacker can extract all distinct field values for any schema field type that has a registered query builder, including string, integer, float, select, boolean, date, slug, and relationship fields. Fields protected with viewPermission are similarly exposed, and the counts variant additionally reveals how many documents have each distinct value. Both the piece-type and page REST APIs are affected. This issue has been fixed in version 4.29.0.

Record
CVE-2026-39857
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Weakness
CWE-200
Updated
2026-11-02
OSV 5.3

Information Disclosure via `choices`/`counts` Query Parameters Bypassing publicApiProjection Field Restrictions

ApostropheCMS is an open-source Node.js content management system. Versions 4.28.0 and prior contain an authorization bypass vulnerability in the choices and counts query parameters of the REST API, where these query builders execute MongoDB distinct() operations that bypass the publicApiProjection restrictions intended to limit which fields are exposed publicly. The choices and counts parameters are processed via applyBuildersSafely before the projection is applied, and MongoDB's distinct operation does not respect projections, returning all distinct values directly. The results are returned in the API response without any filtering against publicApiProjection or removeForbiddenFields. An unauthenticated attacker can extract all distinct field values for any schema field type that has a registered query builder, including string, integer, float, select, boolean, date, slug, and relationship fields. Fields protected with viewPermission are similarly exposed, and the counts variant additionally reveals how many documents have each distinct value. Both the piece-type and page REST APIs are affected. This issue has been fixed in version 4.29.0.

Record
CVE-2026-39857
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Weakness
CWE-200
Updated
2026-11-02
OSVGHSA-c276-fj82-f2pq 5.3

ApostropheCMS: Information Disclosure via choices/counts Query Parameters Bypassing publicApiProjection Field Restrictions

Summary

The choices and counts query parameters in the Apostrophe CMS REST API allow unauthenticated users to extract distinct field values for any schema field that has a registered query builder, completely bypassing publicApiProjection restrictions that are intended to limit which fields are exposed publicly. Fields protected by viewPermission are similarly exposed.

Details

When a piece type configures publicApiProjection to enable public API access while restricting visible fields, the restriction is enforced via a MongoDB projection on the main query (piece-type/index.js:1130-1134). However, the choices and counts query builders bypass this protection through a separate code path.

The vulnerable flow:

  1. getRestQuery at piece-type/index.js:1120 calls applyBuildersSafely(req.query) (line 1122), which processes query parameters including choices and counts since both have launder methods (doc-type/index.js:2627-2628 and 2675-2676).

  2. The publicApiProjection is applied afterward (line 1130-1134) as a MongoDB projection on the main query.

  3. During query execution, the choices builder's after handler (doc-type/index.js:2636-2668) iterates over requested field names. The only validation is:

    • The field has a registered builder (_.has(query.builders, filter) at line 2651)
    • The builder has a launder method (line 2656)

    All schema field types (string, integer, float, select, boolean, date, slug, relationship) register query builders with launder methods via addQueryBuilder in addFieldTypes.js.

  4. toChoices (line 2661) calls the field's choices function, which typically calls sortedDistinct → toDistinct. The toDistinct method (doc-type/index.js:2811) executes db.distinct(property, criteria) — a MongoDB operation that returns all distinct values for the given property matching the criteria. MongoDB's distinct operation does not respect projections; it operates directly on the specified field regardless of any projection set on the query.

  5. The results are stored via query.set('choicesResults', choices) (line 2666) and returned directly in the API response at piece-type/index.js:292-296 without any filtering against publicApiProjection or removeForbiddenFields.

The same bypass applies to viewPermission-protected fields: removeForbiddenFields (doc-type/index.js:1585-1611) only processes document results from toArray(), not the separate choices/counts data.

The page REST API has the same issue at page/index.js:371-376.

PoC

# Prerequisites:
# - An Apostrophe 4.x instance with a piece type configured with publicApiProjection
# - Example: an 'article' piece type with:
#   publicApiProjection: { title: 1, slug: 1, _url: 1 }
#   and additional schema fields like 'status' (select), 'priority' (integer),
#   or 'internalNotes' (string) NOT in the projection

# 1. Verify normal API access only returns projected fields
curl -s 'http://localhost:3000/api/v1/article' | python3 -m json.tool
# Response results contain only: title, slug, _url (as configured)

# 2. Extract distinct values of a non-projected field via choices
curl -s 'http://localhost:3000/api/v1/article?choices=status' | python3 -m json.tool
# Response includes:
# "choices": {"status": [{"value": "draft", "label": "draft"}, {"value": "published", "label": "published"}, ...]}

# 3. Extract distinct values with document counts via counts
curl -s 'http://localhost:3000/api/v1/article?counts=priority' | python3 -m json.tool
# Response includes:
# "counts": {"priority": [{"value": 1, "label": "1", "count": 15}, {"value": 2, "label": "2", "count": 8}, ...]}

# 4. Multiple fields can be extracted at once
curl -s 'http://localhost:3000/api/v1/article?choices=status,priority,internalNotes'

Impact

  • Distinct field values leaked: An unauthenticated attacker can extract all distinct values of any schema field on any piece type that has publicApiProjection…
Record
GHSA-c276-fj82-f2pq
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Weakness
CWE-200
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
apostrophe
npm
through 4.28.0
4.29.0
apostrophe
npm
before 4.29.0
4.29.0

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-39857 is a medium vulnerability (CVSS 5.3) in Apostrophecms Apostrophe, published April 15, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.43%, the 38th percentile. Fixed in apostrophe 4.29.0.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open