GHSA-M2M5-RW3W-CWMJ

Vulnerability from github – Published: 2026-10-20 18:18 – Updated: 2026-10-20 18:18
VLAI
Summary
ApostropheCMS: Client-side Prototype Pollution in apos.http.parseQuery leading to DOM-based XSS against authenticated users
Details

Summary

The client-side helper apos.http.parseQuery() in ApostropheCMS builds a nested object from a URL query string without sanitizing the keys __proto__, constructor, or prototype. Parsing an attacker-controlled query string therefore writes arbitrary properties onto Object.prototype (client-side prototype pollution).

ApostropheCMS's admin UI calls this parser with window.location.search on every authenticated page load (the admin context bar's data() initializer). Because the admin UI is built on Vue, a polluted, enumerable property on Object.prototype is then picked up by Vue's standard element-mount routine and written to the DOM as an element property, turning the prototype pollution into DOM-based XSS in the victim's authenticated session. The escalation gadget is a well-known, general Vue behavior; the novel, reportable defect is the unsanitized parseQuery source together with the authenticated trigger, both of which are ApostropheCMS code.

Any user who can get any logged-in user (from the lowest-privileged guest role up to the highest-privileged admin role) to open a crafted URL can execute arbitrary JavaScript in that user's session.

This is distinct from CVE-2026-53609 (server-side prototype pollution via apos.util.set() / $pullAll, fixed in 4.31.0): different side (client vs server), different code path, and the vulnerable code here is present in the current release.

Package

  • Ecosystem: npm
  • Package: apostrophe
  • Affected versions: all 4.x releases, 4.0.0 through 4.32.2 (current latest). Verified by inspecting the published npm tarballs: apostrophe@4.0.0 already contains the vulnerable descent (parentKey = 'root') with no __proto__/constructor/prototype filtering, and apostrophe@4.32.2 is unchanged in this respect. The vulnerable parseQuery() logic was introduced in commit 0255086bf (2020-11-12), well before the 4.0 version, so ApostropheCMS 3.x is also affected (the same code ships in 3.x at the older build path modules/@apostrophecms/util/ui/public/2-http.js).
  • Patched versions: none at time of writing.

Details

The issue has three parts. Parts 1 and 2 are ApostropheCMS code and constitute the reportable vulnerability. Part 3 is the escalation gadget, which is standard Vue behavior and is included for completeness.

1. The pollution primitive: source (ApostropheCMS)

modules/@apostrophecms/util/ui/src/http.js, function apos.http.parseQuery() (line ~301) and its inner patch() (lines ~317–354):

function patch(key, value) {
  let match;
  let parentKey = 'root';
  let context = data;                    // data = {}  (ordinary object)
  key = decodeURIComponent(key);
  const path = key.split('[');
  path.forEach(function(subKey) {
    if (subKey === ']') {
      /* array handling */
    } else if (subKey.match(/^\d+]/)) {
      /* numeric index handling */
    } else {
      match = subKey.replace(']', '');
      if (!context[parentKey]) {         // (A) truthy check, not an own-property check
        context[parentKey] = {};
      }
      context = context[parentKey];      // (B) descends into whatever this resolves to
      parentKey = match;
    }
  });
  value = (value === null) ? value : decodeURIComponent(value);
  if (Array.isArray(context[parentKey])) {
    context[parentKey].push(value);
  } else if (context[parentKey] !== undefined) {
    context[parentKey] = [ context[parentKey], value ];
  } else {
    context[parentKey] = value;          // (C) assignment onto the resolved object
  }
}

No __proto__, constructor, or prototype key is rejected. Walking the input __proto__[x]=v:

  1. Segment __proto__: at (A), context['__proto__'] resolves to the object's inherited prototype (truthy), so the {} initializer is skipped; at (B), context becomes Object.prototype.
  2. Segment x: at (C), Object.prototype['x'] = v.

The truthy guard at (A) (rather than an own-property check) is what allows the descent into the inherited prototype. Because the assignment at (C) is an ordinary property write, the resulting Object.prototype property is enumerable,which matters for the gadget (3).

2. The trigger: reached on every authenticated page load (ApostropheCMS)

modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue. The component's data() initializer (line ~64) runs when the admin context bar mounts (i.e. on every authenticated page load), and passes the raw query string straight into the vulnerable parser:

data() {
  const query = apos.http.parseQuery(location.search);   // <- attacker-controlled -> (1) pollution, on mount
  const draftMode = query.aposMode || 'published';
  // ...
}

The same component's refresh() method (line ~606) passes window.location.search into parseQuery() again on admin-bar refresh events, and folds it into doc._url (re-parsed inside apos.http.remote()), providing additional trigger points.

The admin context bar mounts only when a session is present and the admin bundle loads, so none of this executes for anonymous visitors, which is why the pollution is observed only when logged in. All of this is core ApostropheCMS code (node_modules/apostrophe/...); it is not introduced by any project or starter kit content.

3. The escalation gadget: Vue element mount (framework behavior; known, not novel)

The demonstrated payload pollutes the property innerHTML (__proto__[innerHTML]=<img/src/onerror=alert(1)>). The sink that consumes it is Vue's standard element-mount path, not ApostropheCMS code. Confirmed in the bundled framework (vue / @vue/runtime-core / @vue/runtime-dom all 3.5.42):

@vue/runtime-core mountElement, prop enumeration (line ~5741):

if (props) {
  for (const key in props) {                              // for...in walks the prototype chain
    if (key !== "value" && !shared.isReservedProp(key)) { // isReservedProp does NOT list innerHTML
      hostPatchProp(el, key, null, props[key], ...);      // props["innerHTML"] → inherited polluted value
    }
  }

@vue/runtime-dom patchDOMProp (line ~583), reached via hostPatchProp:

function patchDOMProp(el, key, value, ...) {
  if (key === "innerHTML" || key === "textContent") {
    if (value != null) {
      el[key] = key === "innerHTML" ? unsafeToTrustedHTML(value) : value;  // el.innerHTML = payload
    }
    return;
  }

Mechanism: whenever Vue mounts an element that has a non-null props object without its own innerHTML (routine during the admin render), for (const key in props) enumerates the inherited, enumerable innerHTML from Object.prototype; it passes the "value" and isReservedProp filters; props["innerHTML"] resolves to the attacker's payload; and patchDOMProp writes it to el.innerHTML. unsafeToTrustedHTML is Vue's Trusted-Types wrapper, not a sanitizer, a passthrough unless Trusted Types is enforced (not the default).

This gadget is a well-documented, essentially universal client-side-PP > XSS escalation in Vue applications. It is not claimed as a novel finding and is not ApostropheCMS's to fix, it cannot be removed without changing Vue. Its relevance here is that it makes the (1) pollution reliably exploitable in any ApostropheCMS admin session.

Proof of Concept

Prerequisite: a running ApostropheCMS instance and any authenticated session (a guest account suffices). The tester/victim must be logged in.

A. Prototype pollution (console-verifiable):

  1. Log in as any user.
  2. Navigate to: https://TARGET/?__proto__[prop]=polluted
  3. In the browser console: Object.prototype.prop > returns "polluted".

B. DOM-based XSS:

  1. Log in as any user.
  2. Navigate to: https://TARGET/?__proto__[innerHTML]=%3Cimg/src/onerror%3dalert(1)%3E
  3. alert(1) executes in the victim's authenticated origin.

To capture the sink stack for evidence: DevTools > Sources > open the admin bundle > pretty-print > search unsafeToTrustedHTML (or === "innerHTML") > line breakpoint in the patchDOMProp innerHTML branch > reload the logged-in payload URL > inspect value and walk the call stack up through hostPatchProp to mountElement's for…in.

Both A and B were reproduced against ApostropheCMS 4.32.2 (Vue 3.5.42) in Chrome, Firefox, and Edge browsers.

Impact

Any party who can coerce an authenticated ApostropheCMS user to open a crafted URL can execute arbitrary JavaScript in that user's session. Because the escalation gadget is a guaranteed-present Vue behavior, this is a reliable exploit, not a theoretical primitive. Consequences scale with the victim's role:

  • Any authenticated victim: actions and data reads available to that account; theft of the session cookie / CSRF token from the authenticated context.
  • Editor/admin victim: the injected script can invoke the authenticated management REST APIs as the victim, creating or modifying documents and user accounts, changing configuration and possibly leading to account takeover and potential full compromise of the CMS instance.

Prototype pollution can additionally affect unrelated code paths that read inherited properties, so other gadgets beyond the demonstrated Vue innerHTML sink may exist.

Remediation

The fix belongs in ApostropheCMS, at the source (1). The gadget (3) is framework behavior and cannot be relied upon to change, so sanitizing parseQuery is the correct fix.

Primary fix: reject prototype-affecting keys in parseQuery/patch():

apos.http.parseQuery = function(query) {
  query = query.replace(/^\?/, '');
  const data = {};
  const DANGEROUS = new Set([ '__proto__', 'constructor', 'prototype' ]);
  query.split('&').forEach(function(pair) {
    // ... unchanged ...
  });
  return data.root || {};

  function patch(key, value) {
    let match;
    let parentKey = 'root';
    let context = data;
    key = decodeURIComponent(key);
    const path = key.split('[');
    let dangerous = false;
    path.forEach(function(subKey) {
      const cleanKey = subKey.replace(']', '');
      if (DANGEROUS.has(cleanKey)) {   // refuse to traverse into prototype-affecting keys
        dangerous = true;
        return;
      }
      // ... existing subKey handling ...
    });
    if (dangerous) {
      return;                          // discard this parameter entirely
    }
    // ... existing assignment ...
  }
};

Defense in depth: - Replace the truthy guard at (A) with an own-property check: if (!Object.prototype.hasOwnProperty.call(context, parentKey)), so a key can never descend into an inherited prototype. - Build data and any created containers with Object.create(null) so intermediate objects have no prototype chain to reach.

Interim mitigation for operators: restrict who holds authenticated accounts, and be aware that opening untrusted links while logged in can trigger this. There is no server-side configuration toggle that disables the vulnerable client behavior.

References

  • Source (ApostropheCMS): apostrophe/modules/@apostrophecms/util/ui/src/http.js — parseQuery() / patch()
  • Trigger (ApostropheCMS): apostrophe/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue — data() (~line 64), refresh() (~line 606)
  • Escalation gadget (Vue 3.5.42, framework behavior): @vue/runtime-core mountElement prop enumeration (~line 5741); @vue/runtime-dom patchDOMProp innerHTML branch (~line 583)
  • Related but distinct: CVE-2026-53609 / GHSA-6h5j-32cf-4253 (server-side prototype pollution via apos.util.set() / $pullAll, fixed in 4.31.0)
  • CWE-1321; CWE-79

Credit

Github Account Username: Xx-LoGiCaL-xX


Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "apostrophe"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.33.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-113659"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1321",
      "CWE-79"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-20T18:18:49Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "## Summary\n\nThe client-side helper `apos.http.parseQuery()` in ApostropheCMS builds a nested object\nfrom a URL query string without sanitizing the keys `__proto__`, `constructor`, or\n`prototype`. Parsing an attacker-controlled query string therefore writes arbitrary\nproperties onto `Object.prototype` (client-side prototype pollution).\n\nApostropheCMS\u0027s admin UI calls this parser with `window.location.search` on **every\nauthenticated page load** (the admin context bar\u0027s `data()` initializer). Because the admin\nUI is built on Vue, a polluted, enumerable property on `Object.prototype` is then picked up\nby Vue\u0027s standard element-mount routine and written to the DOM as an element property,\nturning the prototype pollution into DOM-based XSS in the victim\u0027s authenticated session.\nThe escalation gadget is a well-known, general Vue behavior; the novel,\nreportable defect is the unsanitized `parseQuery` source together with the authenticated\ntrigger, both of which are ApostropheCMS code.\n\nAny user who can get **any logged-in user (from the lowest-privileged `guest` role up to the highest-privileged `admin` role)** to\nopen a crafted URL can execute arbitrary JavaScript in that user\u0027s session.\n\nThis is **distinct from CVE-2026-53609** (server-side prototype pollution via\n`apos.util.set()` / `$pullAll`, fixed in 4.31.0): different side (client vs server),\ndifferent code path, and the vulnerable code here is present in the current release.\n\n## Package\n\n- **Ecosystem:** npm\n- **Package:** `apostrophe`\n- **Affected versions:** all **4.x** releases, **4.0.0 through 4.32.2** (current `latest`).\n  Verified by inspecting the published npm tarballs: `apostrophe@4.0.0` already contains the\n  vulnerable descent (`parentKey = \u0027root\u0027`) with no `__proto__`/`constructor`/`prototype`\n  filtering, and `apostrophe@4.32.2` is unchanged in this respect. The vulnerable\n  `parseQuery()` logic was introduced in commit `0255086bf` (2020-11-12), well before the 4.0\n  version, so **ApostropheCMS 3.x is also affected** (the same code ships in 3.x at the older\n  build path `modules/@apostrophecms/util/ui/public/2-http.js`).\n- **Patched versions:** none at time of writing.\n\n## Details\n\nThe issue has three parts. Parts 1 and 2 are ApostropheCMS code and constitute the\nreportable vulnerability. Part 3 is the escalation gadget, which is standard Vue behavior\nand is included for completeness.\n\n### 1. The pollution primitive: source (ApostropheCMS)\n\n`modules/@apostrophecms/util/ui/src/http.js`, function `apos.http.parseQuery()`\n(line ~301) and its inner `patch()` (lines ~317\u2013354):\n\n```js\nfunction patch(key, value) {\n  let match;\n  let parentKey = \u0027root\u0027;\n  let context = data;                    // data = {}  (ordinary object)\n  key = decodeURIComponent(key);\n  const path = key.split(\u0027[\u0027);\n  path.forEach(function(subKey) {\n    if (subKey === \u0027]\u0027) {\n      /* array handling */\n    } else if (subKey.match(/^\\d+]/)) {\n      /* numeric index handling */\n    } else {\n      match = subKey.replace(\u0027]\u0027, \u0027\u0027);\n      if (!context[parentKey]) {         // (A) truthy check, not an own-property check\n        context[parentKey] = {};\n      }\n      context = context[parentKey];      // (B) descends into whatever this resolves to\n      parentKey = match;\n    }\n  });\n  value = (value === null) ? value : decodeURIComponent(value);\n  if (Array.isArray(context[parentKey])) {\n    context[parentKey].push(value);\n  } else if (context[parentKey] !== undefined) {\n    context[parentKey] = [ context[parentKey], value ];\n  } else {\n    context[parentKey] = value;          // (C) assignment onto the resolved object\n  }\n}\n```\n\nNo `__proto__`, `constructor`, or `prototype` key is rejected. Walking the input\n`__proto__[x]=v`:\n\n1. Segment `__proto__`: at **(A)**, `context[\u0027__proto__\u0027]` resolves to the object\u0027s\n   inherited prototype (truthy), so the `{}` initializer is skipped; at **(B)**, `context`\n   becomes `Object.prototype`.\n2. Segment `x`: at **(C)**, `Object.prototype[\u0027x\u0027] = v`.\n\nThe truthy guard at **(A)** (rather than an own-property check) is what allows the descent\ninto the inherited prototype. Because the assignment at **(C)** is an ordinary property\nwrite, the resulting `Object.prototype` property is **enumerable**,which matters for the\ngadget (3).\n\n### 2. The trigger: reached on every authenticated page load (ApostropheCMS)\n\n`modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue`. The component\u0027s\n`data()` initializer (line ~64) runs when the admin context bar mounts (i.e. on every\nauthenticated page load), and passes the raw query string straight into the vulnerable\nparser:\n\n```js\ndata() {\n  const query = apos.http.parseQuery(location.search);   // \u003c- attacker-controlled -\u003e (1) pollution, on mount\n  const draftMode = query.aposMode || \u0027published\u0027;\n  // ...\n}\n```\n\nThe same component\u0027s `refresh()` method (line ~606) passes `window.location.search` into\n`parseQuery()` again on admin-bar refresh events, and folds it into `doc._url`\n(re-parsed inside `apos.http.remote()`), providing additional trigger points.\n\nThe admin context bar mounts only when a session is present and the admin bundle loads, so\nnone of this executes for anonymous visitors, which is why the pollution is observed **only\nwhen logged in**. All of this is core ApostropheCMS code (`node_modules/apostrophe/...`);\nit is not introduced by any project or starter kit content.\n\n### 3. The escalation gadget: Vue element mount (framework behavior; known, not novel)\n\nThe demonstrated payload pollutes the property `innerHTML`\n(`__proto__[innerHTML]=\u003cimg/src/onerror=alert(1)\u003e`). The sink that consumes it is **Vue\u0027s\nstandard element-mount path**, not ApostropheCMS code. Confirmed in the bundled framework\n(`vue` / `@vue/runtime-core` / `@vue/runtime-dom` all **3.5.42**):\n\n`@vue/runtime-core` `mountElement`, prop enumeration (line ~5741):\n\n```js\nif (props) {\n  for (const key in props) {                              // for...in walks the prototype chain\n    if (key !== \"value\" \u0026\u0026 !shared.isReservedProp(key)) { // isReservedProp does NOT list innerHTML\n      hostPatchProp(el, key, null, props[key], ...);      // props[\"innerHTML\"] \u2192 inherited polluted value\n    }\n  }\n```\n\n`@vue/runtime-dom` `patchDOMProp` (line ~583), reached via `hostPatchProp`:\n\n```js\nfunction patchDOMProp(el, key, value, ...) {\n  if (key === \"innerHTML\" || key === \"textContent\") {\n    if (value != null) {\n      el[key] = key === \"innerHTML\" ? unsafeToTrustedHTML(value) : value;  // el.innerHTML = payload\n    }\n    return;\n  }\n```\n\nMechanism: whenever Vue mounts an element that has a non-null `props` object without its own\n`innerHTML` (routine during the admin render), `for (const key in props)` enumerates the\ninherited, enumerable `innerHTML` from `Object.prototype`; it passes the `\"value\"` and\n`isReservedProp` filters; `props[\"innerHTML\"]` resolves to the attacker\u0027s payload; and\n`patchDOMProp` writes it to `el.innerHTML`. `unsafeToTrustedHTML` is Vue\u0027s Trusted-Types\nwrapper, not a sanitizer, a passthrough unless Trusted Types is enforced (not the default).\n\nThis gadget is a well-documented, essentially universal client-side-PP \u003e XSS escalation in Vue applications.\nIt is **not claimed as a novel finding** and is **not ApostropheCMS\u0027s to fix**, it cannot\nbe removed without changing Vue. Its relevance here is that it makes the (1) pollution\nreliably exploitable in any ApostropheCMS admin session.\n\n## Proof of Concept\n\nPrerequisite: a running ApostropheCMS instance and any authenticated session (a `guest`\naccount suffices). The tester/victim must be logged in.\n\n**A. Prototype pollution (console-verifiable):**\n\n1. Log in as any user.\n2. Navigate to: `https://TARGET/?__proto__[prop]=polluted`\n3. In the browser console: `Object.prototype.prop` \u003e returns `\"polluted\"`.\n\n**B. DOM-based XSS:**\n\n1. Log in as any user.\n2. Navigate to:\n   `https://TARGET/?__proto__[innerHTML]=%3Cimg/src/onerror%3dalert(1)%3E`\n3. `alert(1)` executes in the victim\u0027s authenticated origin.\n\nTo capture the sink stack for evidence: DevTools \u003e Sources \u003e open the admin bundle \u003e\npretty-print \u003e search `unsafeToTrustedHTML` (or `=== \"innerHTML\"`) \u003e line breakpoint in the\n`patchDOMProp` innerHTML branch \u003e reload the logged-in payload URL \u003e inspect `value` and\nwalk the call stack up through `hostPatchProp` to `mountElement`\u0027s `for\u2026in`.\n\nBoth A and B were reproduced against ApostropheCMS 4.32.2 (Vue 3.5.42) in Chrome, Firefox, and Edge browsers.\n\n## Impact\n\nAny party who can coerce an authenticated ApostropheCMS user to open a crafted URL can\nexecute arbitrary JavaScript in that user\u0027s session. Because the escalation gadget is a\nguaranteed-present Vue behavior, this is a reliable exploit, not a theoretical primitive.\nConsequences scale with the victim\u0027s role:\n\n- **Any authenticated victim:** actions and data reads available to that account; theft of\n  the session cookie / CSRF token from the authenticated context.\n- **Editor/admin victim:** the injected script can invoke the authenticated management REST\n  APIs as the victim, creating or modifying documents and user accounts, changing\n  configuration and possibly leading to account takeover and potential full compromise of the CMS\n  instance.\n\nPrototype pollution can additionally affect unrelated code paths that read inherited\nproperties, so other gadgets beyond the demonstrated Vue `innerHTML` sink may exist.\n\n## Remediation\n\nThe fix belongs in ApostropheCMS, at the source (1). The gadget (3) is framework behavior\nand cannot be relied upon to change, so sanitizing `parseQuery` is the correct fix.\n\n**Primary fix: reject prototype-affecting keys in `parseQuery`/`patch()`**:\n\n```js\napos.http.parseQuery = function(query) {\n  query = query.replace(/^\\?/, \u0027\u0027);\n  const data = {};\n  const DANGEROUS = new Set([ \u0027__proto__\u0027, \u0027constructor\u0027, \u0027prototype\u0027 ]);\n  query.split(\u0027\u0026\u0027).forEach(function(pair) {\n    // ... unchanged ...\n  });\n  return data.root || {};\n\n  function patch(key, value) {\n    let match;\n    let parentKey = \u0027root\u0027;\n    let context = data;\n    key = decodeURIComponent(key);\n    const path = key.split(\u0027[\u0027);\n    let dangerous = false;\n    path.forEach(function(subKey) {\n      const cleanKey = subKey.replace(\u0027]\u0027, \u0027\u0027);\n      if (DANGEROUS.has(cleanKey)) {   // refuse to traverse into prototype-affecting keys\n        dangerous = true;\n        return;\n      }\n      // ... existing subKey handling ...\n    });\n    if (dangerous) {\n      return;                          // discard this parameter entirely\n    }\n    // ... existing assignment ...\n  }\n};\n```\n\n**Defense in depth:**\n- Replace the truthy guard at **(A)** with an own-property check:\n  `if (!Object.prototype.hasOwnProperty.call(context, parentKey))`, so a key can never\n  descend into an inherited prototype.\n- Build `data` and any created containers with `Object.create(null)` so intermediate objects\n  have no prototype chain to reach.\n\n**Interim mitigation for operators:** restrict who holds authenticated accounts, and be\naware that opening untrusted links while logged in can trigger this. There is no server-side\nconfiguration toggle that disables the vulnerable client behavior.\n\n## References\n\n- Source (ApostropheCMS): `apostrophe/modules/@apostrophecms/util/ui/src/http.js` \u2014\n  `parseQuery()` / `patch()`\n- Trigger (ApostropheCMS):\n  `apostrophe/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue` \u2014\n  `data()` (~line 64), `refresh()` (~line 606)\n- Escalation gadget (Vue 3.5.42, framework behavior): `@vue/runtime-core` `mountElement`\n  prop enumeration (~line 5741); `@vue/runtime-dom` `patchDOMProp` innerHTML branch\n  (~line 583)\n- Related but distinct: CVE-2026-53609 / GHSA-6h5j-32cf-4253 (server-side prototype\n  pollution via `apos.util.set()` / `$pullAll`, fixed in 4.31.0)\n- CWE-1321; CWE-79\n\n## Credit\n\n### Github Account Username: `Xx-LoGiCaL-xX`\n\n---",
  "id": "GHSA-m2m5-rw3w-cwmj",
  "modified": "2026-10-20T18:18:49Z",
  "published": "2026-10-20T18:18:49Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-m2m5-rw3w-cwmj"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apostrophecms/apostrophe/commit/9500b8b0e1d630d5e07fbb5fd2c25ed0943845ce"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apostrophecms/apostrophe/commit/f84fd41cbf6c22eb8d0008fc9c25df1f7130b350"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/apostrophecms/apostrophe"
    },
    {
      "type": "WEB",
      "url": "https://github.com/apostrophecms/apostrophe/releases/tag/apostrophe@4.33.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "ApostropheCMS: Client-side Prototype Pollution in apos.http.parseQuery leading to DOM-based XSS against authenticated users"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.