Skip to content
Heist/ feed
Back to feed
HighFix available

ApostropheCMS: Authenticated projection-exclusion prototype-member deletion in @apostrophecms/db-connect causes process-wide denial of service

Type: advisorySources: OSV

## Summary `@apostrophecms/db-connect` ships an in-memory MongoDB emulation used by its SQLite, PostgreSQL, and multipostgres adapters. Its `unsetNestedField` helper walks an attacker-controlled dotted field path with no segment validation and calls `delete` on the resolved property. A low-privileged authenticated user (any role holding `view-draft`, which every editor and contributor has; reduced to any logged-in user when `guestApiAccess` is enabled) can send a piece-type REST GET request whose `project` query builder contains an exclusion key such as `constructor.prototype.hasOwnProperty`. On a SQLite or PostgreSQL adapter this key reaches `unsetNestedField`, which resolves `Object.prototype` and deletes a shared runtime method. Because that method is shared across the whole Node process, the deletion breaks request handling for every tenant and user until the process is restarted, giving a single request a persistent denial of service. ## Root Cause The projection query builder laundens only projection values, never projection keys, so an arbitrary dotted key survives to the database layer. On the SQLite and PostgreSQL adapters an exclusion projection is applied in JavaScript by `applyProjection`, which for each excluded field calls `unsetNestedField(result, field)`. `unsetNestedField` splits the field on `.` and walks the resulting segments with no guard: unlike its sibling `setNestedField`, it does not even block a literal `__proto__`, and neither helper blocks `constru

Products
@apostrophecms/db-connect, apostrophe
Affected versions
Not specified
Fixed versions
1.1.0, 4.33.0
CVEs
CVE-2026-113666
Confirmed fixed CVEs
Not specified
Updated in this feed
31 Oct 2026, 13:14 UTC · Revision 1

Source evidence

ApostropheCMS: Authenticated projection-exclusion prototype-member deletion in @apostrophecms/db-connect causes process-wide denial of service

core-osv · Original source

Published 20 Oct 2026, 18:03 UTC

## Summary `@apostrophecms/db-connect` ships an in-memory MongoDB emulation used by its SQLite, PostgreSQL, and multipostgres adapters. Its `unsetNestedField` helper walks an attacker-controlled dotted field path with no segment validation and calls `delete` on the resolved property. A low-privileged authenticated user (any role holding `view-draft`, which every editor and contributor has; reduced to any logged-in user when `guestApiAccess` is enabled) can send a piece-type REST GET request whose `project` query builder contains an exclusion key such as `constructor.prototype.hasOwnProperty`. On a SQLite or PostgreSQL adapter this key reaches `unsetNestedField`, which resolves `Object.prototype` and deletes a shared runtime method. Because that method is shared across the whole Node process, the deletion breaks request handling for every tenant and user until the process is restarted, giving a single request a persistent denial of service. ## Root Cause The projection query builder laundens only projection values, never projection keys, so an arbitrary dotted key survives to the database layer. On the SQLite and PostgreSQL adapters an exclusion projection is applied in JavaScript by `applyProjection`, which for each excluded field calls `unsetNestedField(result, field)`. `unsetNestedField` splits the field on `.` and walks the resulting segments with no guard: unlike its sibling `setNestedField`, it does not even block a literal `__proto__`, and neither helper blocks `constru

osv:GHSA-j5rq-xfvr-p969

@apostrophecms/db-connect

Fixed versions: 1.1.0

apostrophe

Fixed versions: 4.33.0

Complete source record
{
  "id": "43d765f351155008b5061fd12fdf03489ee955c999a5d37aa62fefadaa789fa1",
  "url": "https://osv.dev/vulnerability/GHSA-j5rq-xfvr-p969",
  "method": "structured",
  "payload": {
    "kind": "advisory",
    "title": "ApostropheCMS: Authenticated projection-exclusion prototype-member deletion in @apostrophecms/db-connect causes process-wide denial of service",
    "summary": "## Summary `@apostrophecms/db-connect` ships an in-memory MongoDB emulation used by its SQLite, PostgreSQL, and multipostgres adapters. Its `unsetNestedField` helper walks an attacker-controlled dotted field path with no segment validation and calls `delete` on the resolved property. A low-privileged authenticated user (any role holding `view-draft`, which every editor and contributor has; reduced to any logged-in user when `guestApiAccess` is enabled) can send a piece-type REST GET request whose `project` query builder contains an exclusion key such as `constructor.prototype.hasOwnProperty`. On a SQLite or PostgreSQL adapter this key reaches `unsetNestedField`, which resolves `Object.prototype` and deletes a shared runtime method. Because that method is shared across the whole Node process, the deletion breaks request handling for every tenant and user until the process is restarted, giving a single request a persistent denial of service. ## Root Cause The projection query builder laundens only projection values, never projection keys, so an arbitrary dotted key survives to the database layer. On the SQLite and PostgreSQL adapters an exclusion projection is applied in JavaScript by `applyProjection`, which for each excluded field calls `unsetNestedField(result, field)`. `unsetNestedField` splits the field on `.` and walks the resulting segments with no guard: unlike its sibling `setNestedField`, it does not even block a literal `__proto__`, and neither helper blocks `constru",
    "evidence": "osv:GHSA-j5rq-xfvr-p969",
    "products": [
      {
        "name": {
          "value": "@apostrophecms/db-connect",
          "evidence": "/affected/0/package/name"
        },
        "prerequisites": [],
        "fixed_versions": [
          {
            "value": "1.1.0",
            "evidence": "/affected/0/ranges"
          }
        ],
        "affected_versions": []
      },
      {
        "name": {
          "value": "apostrophe",
          "evidence": "/affected/1/package/name"
        },
        "prerequisites": [],
        "fixed_versions": [
          {
            "value": "4.33.0",
            "evidence": "/affected/1/ranges"
          }
        ],
        "affected_versions": []
      }
    ],
    "severity": "high",
    "structured": {
      "id": "GHSA-j5rq-xfvr-p969",
      "aliases": [
        "CVE-2026-113666",
        "GHSA-j5rq-xfvr-p969"
      ],
      "metrics": [
        {
          "type": "CVSS_V3",
          "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H"
        }
      ],
      "affected": [
        {
          "ranges": [
            {
              "type": "SEMVER",
              "events": [
                {
                  "introduced": "0"
                },
                {
                  "fixed": "1.1.0"
                }
              ]
            }
          ],
          "package": {
            "name": "@apostrophecms/db-connect",
            "purl": "pkg:npm/%40apostrophecms/db-connect",
            "ecosystem": "npm"
          },
          "database_specific": {
            "source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-j5rq-xfvr-p969/GHSA-j5rq-xfvr-p969.json"
          }
        },
        {
          "ranges": [
            {
              "type": "SEMVER",
              "events": [
                {
                  "introduced": "0"
                },
                {
                  "fixed": "4.33.0"
                }
              ]
            }
          ],
          "package": {
            "name": "apostrophe",
            "purl": "pkg:npm/apostrophe",
            "ecosystem": "npm"
          },
          "database_specific": {
            "source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-j5rq-xfvr-p969/GHSA-j5rq-xfvr-p969.json"
          }
        }
      ],
      "modified": "2026-10-20T18:15:04.524962165Z",
      "provider": "osv",
      "references": [
        "https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-j5rq-xfvr-p969",
        "https://github.com/apostrophecms/apostrophe/commit/9500b8b0e1d630d5e07fbb5fd2c25ed0943845ce",
        "https://github.com/apostrophecms/apostrophe/commit/f84fd41cbf6c22eb8d0008fc9c25df1f7130b350",
        "https://github.com/apostrophecms/apostrophe",
        "https://github.com/apostrophecms/apostrophe/releases/tag/@apostrophecms/db-connect@1.1.0",
        "https://github.com/apostrophecms/apostrophe/releases/tag/apostrophe@4.33.0"
      ],
      "provider_metadata": {
        "cwe_ids": [
          "CWE-1321",
          "CWE-400"
        ],
        "severity": "HIGH",
        "github_reviewed": true,
        "nvd_published_at": null,
        "github_reviewed_at": "2026-10-20T18:03:50Z"
      }
    },
    "related_cves": [
      {
        "value": "CVE-2026-113666",
        "evidence": "/aliases"
      }
    ],
    "security_relevant": true,
    "severity_evidence": "/database_specific/severity"
  },
  "source_id": "core-osv",
  "document_id": 390138,
  "published_at": "2026-10-20T18:03:50+00:00"
}