---
id: "CVE-2026-112957"
kind: "vulnerability"
aliases: ["CVE-2026-112957", "GHSA-vh56-5m88-39rq"]
title: "ApostropheCMS: GET /api/v1/@apostrophecms/page/:id bypasses viewRole restriction and exposes viewPermission-gated fields to lower-privileged users"
severity: "medium"
cvss: 4.300000190734863
epss: 0.0025100000202655792
exploited: false
status: "open"
category: "package"
products: [{"name": "apostrophe", "fixed": ["4.34.0"], "affected": "< 4.34.0", "ecosystem": "npm"}]
ecosystems: ["npm"]
tags: ["apostrophe", "cms", "cwe-862", "node", "package", "self-hosted"]
not_affected_if: ["editor-role-untrusted-users-absent", "no-viewrole-or-viewpermission-usage", "version-4.34.0-or-later"]
published_at: "2026-10-20T17:17:33+00:00"
first_seen_at: "2026-10-23T19:11:32+00:00"
updated_at: "2026-10-23T21:57:20+00:00"
sources: [{"source": "ghsa", "url": "https://github.com/advisories/GHSA-vh56-5m88-39rq", "first_seen_at": "2026-10-23T19:11:32+00:00"}, {"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-112957", "first_seen_at": "2026-10-23T21:57:20+00:00"}]
---

# ApostropheCMS: GET /api/v1/@apostrophecms/page/:id bypasses viewRole restriction and exposes viewPermission-gated fields to lower-privileged users

ApostropheCMS's single-page REST endpoint GET /api/v1/@apostrophecms/page/:id skips the viewRole and viewPermission checks that the list endpoint enforces. An editor-level user who knows or guesses a page _id can read admin-only pages and fields gated by viewPermission.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- npm:apostrophe affected < 4.34.0 fixed 4.34.0

## How to check

Check the installed apostrophe version in package.json or package-lock.json (npm ls apostrophe); affected if below 4.34.0.
Search the project for viewRole or viewPermission to see whether any page types or fields rely on them.

## Fix

Upgrade apostrophe to 4.34.0 or later.

## Timeline

- 2026-10-23T19:11:32+00:00 ghsa https://github.com/advisories/GHSA-vh56-5m88-39rq
- 2026-10-23T21:57:20+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-112957

## From the sources

### 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
```bash
# 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.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
