GHSA-vh56-5m88-39rq CVE-2026-112957
ApostropheCMS: GET /api/v1/@apostrophecms/page/:id bypasses viewRole restriction and exposes viewPermission-gated fields to lower-privileged users
- Severity
- 4.3 / 10
- Medium · CVSS 3.1
- Exploit chance (EPSS)
- 0.31%
- Chance of exploitation in the next 30 days. Higher than 23.49% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-862 Missing Authorization
- Fix
4.34.0- Upgrade apostrophe to this version or later
Description
Summary
The getOne REST endpoint for pages does not apply viewRole type-level restrictions
or viewPermission field-level redaction. An editor-level user who knows a document
_id can read the full content of admin-only pages and their privileged fields, while
the getAll endpoint correctly enforces both restrictions.
Details
Finding 3 — viewRole bypass:
modules/@apostrophecms/page/index.js exposes getRestQuery(req, omitPermissionCheck = false). The getAll path calls publicApiCheckAsync and threads the full query builder
pipeline including viewRole filtering. The getOne path uses a divergent code path
that skips this pipeline.
A page type declared with viewRole: 'admin' is inaccessible via GET /api/v1/@apostrophecms/page?type=secretPage (returns 403 to an editor) but is fully
returned by GET /api/v1/@apostrophecms/page/:id:en:published to the same editor.
Finding 4 — viewPermission field leak:
Fields decorated with viewPermission: { action: 'edit', type: '@apostrophecms/page' }
are stripped by removeForbiddenFields in the getAll path but are returned verbatim
in getOne. An editor who knows any document _id can read all
viewPermission-restricted fields.
PoC
# Log in as editor, get session jar
EDITOR_JAR="..."
# getAll — correctly blocked
curl -b "$EDITOR_JAR" \
"http://TARGET/api/v1/@apostrophecms/page?type=secretPage"
# → 403 Forbidden
# getOne — bypassed, returns full document including viewPermission fields
curl -b "$EDITOR_JAR" \
"http://TARGET/api/v1/@apostrophecms/page/ADMIN_PAGE_ID:en:published"
# → 200 OK, full doc including secretField value
Impact
Editors can read the full content of any page — including those restricted to admins via
viewRole — if they know or can guess the _id. Sensitive field values gated by
viewPermission are also fully exposed. This breaks the content access control model
for any site using these decorators.
Affected versions
npm
| Package | Vulnerable | Fixed in |
|---|---|---|
| apostrophe | < 4.34.0 |
4.34.0 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
apostrophe npm → 4.34.0
- npm
npm install apostrophe@4.34.0- yarn
yarn add apostrophe@4.34.0- pnpm
pnpm add apostrophe@4.34.0
Severity breakdown
CVSS 3.1 4.3
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- Low
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Weakness
CWE-862: Missing Authorization
The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
How to prevent it
- Architecture and Design: Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) [REF-229] to enforce the roles at the appropriate boundaries. Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
- Architecture and Design: Ensure that access control checks are performed related to the business logic. These checks may be different than the access control checks that are applied to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor [REF-7].
- Architecture and Design: Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, consider using authorization frameworks such as the JAAS Authorization Framework [REF-233] and the OWASP ESAPI Access Control feature [REF-45].
- Architecture and Design: For web applications, make sure that the access control mechanism is enforced correctly at the server side on every page. Users should not be able to access any unauthorized functionality or information by simply requesting direct access to that page. One way to do this is to ensure that all pages containing sensitive information are not cached, and that all such pages restrict access to requests that are accompanied by an active and authenticated session token associated with a user who has the required permissions to access that page.
- System Configuration, Installation: Use the access control capabilities of your operating system and server environment and define your access control lists accordingly. Use a "default deny" policy when defining these ACLs.
References
Advisories
Packages
Other links
- github.com/apostrophecms/apostrophe/security/advisories/GHSA-vh56-5m88-39rq
- github.com/apostrophecms/apostrophe/commit/06e4b377f3c360f9e89c32dccd7e505ad5dd…
- github.com/apostrophecms/apostrophe/commit/40b989b1a9dd23d30029b8ce7668634265cf…
- github.com/apostrophecms/apostrophe/releases/tag/apostrophe@4.34.0
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-86wm-68pq-5jwq ApostropheCMS: Unauthenticated resource exhaustion via pre-auth aposBigUpload processing in @apostrophecms/import-export | High | Also affects apostrophe |
| GHSA-653j-g8j7-gh54 ApostropheCMS: No Attempt Throttling on Authenticated Password-Change Endpoint Enables Unlimited Current-Password Guessing | Medium | Also affects apostrophe |
| GHSA-vwwx-px9w-crrc ApostropheCMS: Missing Authorization on Notification PATCH/DELETE Endpoints | Low | Also affects apostrophe |
| GHSA-vmxh-77cw-65j7 ApostropheCMS: Authenticated Object-Level Authorization Bypass in exist-in-locale Reveals Restricted Localized Draft Identifiers | Medium | Also affects apostrophe |
| GHSA-m2m5-rw3w-cwmj ApostropheCMS: Client-side Prototype Pollution in apos.http.parseQuery leading to DOM-based XSS against authenticated users | Medium | Also affects apostrophe |
| GHSA-gqh3-7856-rjjg ApostropheCMS: :_id/locales REST route omits the public-API authorization gate its sibling read routes enforce (unauthenticated doc-existence + locale metadata disclosure) | Medium | Also affects apostrophe |
| GHSA-hhvr-8m24-qqr3 ApostropheCMS: Cross-domain session token in URL confers session takeover | Medium | Also affects apostrophe |
| GHSA-j5rq-xfvr-p969 ApostropheCMS: Authenticated projection-exclusion prototype-member deletion in @apostrophecms/db-connect causes process-wide denial of service | High | Also affects apostrophe |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor