Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions advisories/BREW-imap-backup-CVE-2026-63435.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"schema_version": "1.7.3",
"id": "BREW-imap-backup-CVE-2026-63435",
"published": "2026-09-03T09:13:37Z",
"modified": "2026-09-03T09:13:37Z",
"upstream": [
"GHSA-mvxr-6m87-mv2q",
"CVE-2026-63435"
],
"affected": [
{
"package": {
"ecosystem": "Homebrew",
"name": "imap-backup",
"purl": "pkg:brew/imap-backup"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "0"
}
]
}
],
"ecosystem_specific": {
"fix": null,
"range_state": "affected",
"upstream_fixed_in": "2.9.1",
"resource": "mail",
"resource_purl": "pkg:gem/mail@2.7.1"
}
}
],
"database_specific": {
"source": "matched",
"strategy": "registry",
"confidence": "high",
"upstream_evidence": [
{
"strategy": "registry",
"ecosystem": "RubyGems",
"name": "mail",
"subject_version": "2.7.1",
"key": "pkg:gem/mail@2.7.1",
"resource": "mail"
}
]
},
"summary": "Mail: Email address spoofing via malformed RFC 2047 encoded-words",
"details": "## Summary\n\nMail::Utilities.q_value_decode and Mail::Utilities.b_value_decode decoded only the first RFC 2047 encoded-word in a string and used an overly greedy pattern to match the charset token. A crafted, malformed encoded-word embedded in an address display name or local part could cause the decoded output to differ from what a human reviewer or downstream parser would expect, allowing an attacker to spoof the apparent sender/recipient address.\n\n## Details\n\nBoth decoders used a single String#match against a pattern such as /\\=\\?(.+)?\\?[Qq]\\?(.*)\\?\\=/m. Two problems:\n\n1. Single match, dropped remainder. Only the first =?charset?Q?...?= (or ?B?) word was decoded. Any additional encoded-words or surrounding text were not handled consistently, so the decoded result could silently omit or alter parts of the input.\n2. Greedy charset capture. (.+)? is greedy and matches across ? delimiters, so a malformed word could span more of the string than a strict RFC 2047 parse would, changing the boundary between \"encoded\" and \"literal\" text.\n\n## Impact\n\nApplications using mail to parse and display or authorize based on decoded header values (From, To, Reply-To, etc.) may present or act on an address different from the one a validator inspecting the raw header would see. Primary risk is spoofing / phishing and authorization-check bypass. No RCE.",
"severity": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N"
}
],
"references": [
{
"type": "WEB",
"url": "https://github.com/mikel/mail/security/advisories/GHSA-mvxr-6m87-mv2q"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-63435"
},
{
"type": "WEB",
"url": "https://github.com/mikel/mail/pull/1664"
},
{
"type": "WEB",
"url": "https://github.com/mikel/mail/commit/f9d59c2e447af42e2c3dec5a56b1bb25c7292859"
},
{
"type": "PACKAGE",
"url": "https://github.com/mikel/mail"
},
{
"type": "WEB",
"url": "https://github.com/mikel/mail/releases/tag/2.9.1"
}
]
}
94 changes: 94 additions & 0 deletions advisories/BREW-pnpm@9-CVE-2026-82392.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"schema_version": "1.7.3",
"id": "BREW-pnpm@9-CVE-2026-82392",
"published": "2026-09-03T09:52:47Z",
"modified": "2026-09-03T09:52:47Z",
"upstream": [
"GHSA-c59q-g84q-2gj5",
"CVE-2026-82392"
],
"affected": [
{
"package": {
"ecosystem": "Homebrew",
"name": "pnpm@9",
"purl": "pkg:brew/pnpm%409"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "0"
}
]
}
],
"ecosystem_specific": {
"fix": null,
"range_state": "affected",
"upstream_fixed_in": "10.34.5"
}
}
],
"database_specific": {
"source": "matched",
"strategy": "registry",
"confidence": "high",
"upstream_evidence": [
{
"strategy": "registry",
"ecosystem": "npm",
"name": "pnpm",
"subject_version": "9.15.9",
"key": "pkg:npm/pnpm@9.15.9"
}
]
},
"summary": "pnpm: Virtual store linker path traversal via unvalidated depPath name in lockfileToDepGraph",
"details": "## Summary\n\nThe virtual store linker constructs package installation directories using `path.join(modules, pkgName)` where `pkgName` is extracted from lockfile `packages` keys via `dp.parse(depPath).name` without validation. A crafted `pnpm-lock.yaml` with traversal sequences in depPath keys (e.g., `../../../tmp/pwned@1.0.0`) causes package content to be written to arbitrary filesystem paths during `pnpm install`.\n\nThis is an incomplete fix of GHSA-fr4h-3cph-29xv — the `safeJoinModulesDir` containment helper was applied to the hoisted linker and `symlinkDependency` but NOT to the virtual store linker's `lockfileToDepGraph.ts:233`.\n\n## Details\n\n### Root Cause\n\n`dp.parse()` at `pnpm11/deps/path/src/index.ts:135` extracts the package name as:\n```typescript\nconst name = dependencyPath.substring(0, sepIndex)\n```\n\nThis is a raw substring operation with zero validation that `name` is a valid npm package name. A depPath of `../../../tmp/pwned@1.0.0` yields `name = '../../../tmp/pwned'`.\n\n### Vulnerable Code Path\n\n1. `pnpm-lock.yaml` → `lockfile.packages['../../../../../../../tmp/pwned@1.0.0']` (attacker-controlled lockfile key)\n2. `nameVerFromPkgSnapshot(depPath, pkgSnapshot)` at `lockfile/utils/src/nameVerFromPkgSnapshot.ts:16` → calls `dp.parse(depPath)` → returns `{ name: '../../../../../../../tmp/pwned' }`\n3. `lockfileToDepGraph.ts:232` → `modules = path.join(dirInVirtualStore, 'node_modules')`\n4. `lockfileToDepGraph.ts:233` → `dir = path.join(modules, pkgName)` → resolves to `/tmp/pwned` (ESCAPES virtual store)\n5. `storeController.importPackage(depNode.dir, ...)` → writes package content to the traversed path\n\n### Why Existing Defenses Don't Catch It\n\n- **`depPathToFilename()`** — replaces `/` with `+` for the `dirInVirtualStore` path, but `pkgName` comes SEPARATELY from `dp.parse()` and is NOT passed through this function\n- **`verifyLockfileResolutions()`** — validates dependency map keys (aliases) via `isValidDependencyAlias()`, but never validates the depPath keys themselves\n- **Lockfile parser** — `yaml.load(lockfileRawContent)` with no schema validation on `packages` keys\n- **`importPackage()`** — accepts `targetDir` and passes it directly to `cafsStore.importPackage(targetDir, ...)` with zero containment check\n- **Integrity verification** — requires a real fetchable package but does not validate the destination path\n\n### Escalation to RCE (non-default config)\n\nWhen `dangerouslyAllowAllBuilds: true` is configured (or the traversal package name is in the explicit `allowBuilds` list), the same traversed path is used in the rebuild phase at `after-install/src/index.ts:402,470`. The attacker's `postinstall` script then executes with the victim's shell access. Under default config, `allowBuild` returns false for unknown packages, limiting impact to arbitrary file write.\n\n### Also Affected (PnP linker)\n\nWhen `nodeLinker: pnp` is configured, `lockfileToPackageRegistry()` at `lockfile/to-pnp/src/index.ts:105-110` uses the same unvalidated `dp.parse().name` in `packageLocation` construction, allowing the `.pnp.cjs` resolver map to point outside the virtual store. This is a lower-impact variant (PnP is not the default linker).\n\n## Impact\n\nAn attacker who can commit a crafted `pnpm-lock.yaml` to a repository (or supply one via a malicious package) can cause arbitrary file writes on the machine of any user who runs `pnpm install`. Written content is the actual package files from a real npm package (attacker controls which package and which destination).\n\nTargets for arbitrary file write include:\n- `.git/hooks/pre-commit` — code execution on next git operation\n- `~/.local/bin/` — binary hijacking\n- Project source files — supply chain injection\n\n## Reproduction\n\nCraft a `pnpm-lock.yaml`:\n```yaml\nlockfileVersion: '9.0'\npackages:\n ../../../../../../../tmp/pwned@1.0.0:\n resolution: {integrity: sha512-<real-package-integrity>}\n engines: {node: '>=14'}\nsnapshots:\n ../../../../../../../tmp/pwned@1.0.0: {}\nimporters:\n .:\n dependencies:\n legitimate-name:\n specifier: ^1.0.0\n version: ../../../../../../../tmp/pwned@1.0.0\n```\n\nRun `pnpm install` — package content is written to `/tmp/pwned/` instead of the virtual store.\n\n## Recommended Fix\n\nApply `safeJoinModulesDir` (or equivalent validation) at:\n- `lockfileToDepGraph.ts:233` — `path.join(modules, pkgName)`\n- `after-install/src/index.ts:402` — `path.join(pkgModulesDir(depPath), pkgInfo.name)`\n- `lockfile/to-pnp/src/index.ts:105-110` — PnP `packageLocation`\n\nAlternatively, validate depPath keys during lockfile parsing to reject any that don't produce valid npm package names via `dp.parse()`.\n\n## Relationship to GHSA-fr4h-3cph-29xv\n\nGHSA-fr4h-3cph-29xv fixed the hoisted linker path (`lockfileToHoistedDepGraph.ts:222`) by adding `safeJoinModulesDir`. The same fix was NOT applied to the virtual store linker, which uses the identical `dp.parse().name → path.join()` pattern at `lockfileToDepGraph.ts:233`.",
"severity": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:L"
}
],
"references": [
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/security/advisories/GHSA-c59q-g84q-2gj5"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-82392"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/pull/12872"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/pull/12890"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/commit/51300fd41c5e4c8f47635108e373cc3d1f324fa7"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/commit/78e29fe5583a1e5d69ea05e414eff310f78d5ed9"
},
{
"type": "PACKAGE",
"url": "https://github.com/pnpm/pnpm"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/releases/tag/v10.34.5"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/releases/tag/v11.11.0"
}
]
}
94 changes: 94 additions & 0 deletions advisories/BREW-pnpm@9-CVE-2026-82393.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"schema_version": "1.7.3",
"id": "BREW-pnpm@9-CVE-2026-82393",
"published": "2026-09-03T09:52:47Z",
"modified": "2026-09-03T09:52:47Z",
"upstream": [
"GHSA-vq4v-j7r6-jq4m",
"CVE-2026-82393"
],
"affected": [
{
"package": {
"ecosystem": "Homebrew",
"name": "pnpm@9",
"purl": "pkg:brew/pnpm%409"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "0"
}
]
}
],
"ecosystem_specific": {
"fix": null,
"range_state": "affected",
"upstream_fixed_in": "10.34.5"
}
}
],
"database_specific": {
"source": "matched",
"strategy": "registry",
"confidence": "high",
"upstream_evidence": [
{
"strategy": "registry",
"ecosystem": "npm",
"name": "pnpm",
"subject_version": "9.15.9",
"key": "pkg:npm/pnpm@9.15.9"
}
]
},
"summary": "pnpm: A tarball dependency's manifest `name` escapes node_modules → arbitrary file write/overwrite on install",
"details": "## Summary\nWhen resolving a package, pnpm uses the resolved **manifest `name`** as a raw path segment for the isolated-linker import target. A tarball dependency whose `package.json` `name` is a scoped path traversal (`@x/../../…/<abs path>`) is therefore extracted **outside `node_modules`**, to an attacker-chosen absolute path, and can **overwrite existing files** there. Attacker controls the destination, filenames, and contents → arbitrary file write → **code execution** (e.g. `~/.zshrc`, `.git/hooks/pre-commit`, another package's code). Occurs during `pnpm install` **even with `--ignore-scripts`** (no lifecycle scripts run), defeating that safety.\n\nSame class as the just-patched **GHSA-hwx4** (transitive-dependency *alias* traversal) and **GHSA-v23m** (`stage download` manifest name/version traversal), in a sink their fixes did not cover: the isolated-linker import target keyed by the resolved **name**.\n\n## Root cause\n- The isolated-linker import target is built with a raw `path.join(modules, <resolved name>)` in `installing/deps-resolver/src/resolvePeers.ts:706`, `installing/deps-resolver/src/index.ts:614`, and `deps/graph-builder/src/lockfileToDepGraph.ts:233` — **without** the `safeJoinModulesDir` guard used on the symlink/hoisted/bin paths (`installing/deps-restorer/src/lockfileToHoistedDepGraph.ts:222`). The store location is `node_modules/.pnpm/<id>/node_modules/<name>`, so a traversal `<name>` escapes.\n- The only resolve-time name gate (`resolving/npm-resolver/src/pickPackage.ts:753`) rejects only *unscoped* names containing `/`, so a **scoped** `@x/../..` passes.\n\n## Steps to reproduce\nSelf-contained PoC (real `pnpm@11.9.0`; loopback tarball server; escape target is a throwaway temp dir):\n```\nnpm i pnpm@11.9.0\n# host a tarball whose package.json name = \"@x/\"+\"../\".repeat(25)+\"<abs>/OUTSIDE\"; victim depends on the http URL\npnpm install --ignore-scripts\n```\nConfirmed output (`repro/poc.mjs`, exit 0):\n```\nescape dir is outside the project : true\nnew file implanted outside node_modules : true\npre-existing file OVERWRITTEN : true\n*** CONFIRMED: a tarball dependency wrote & overwrote files OUTSIDE the project during `pnpm install --ignore-scripts` ***\n```\n\n## Remediation\nRoute the isolated-linker import-target joins (`resolvePeers.ts:706`, `deps-resolver/index.ts:614`, `lockfileToDepGraph.ts:233`) through `safeJoinModulesDir` (as the hoisted linker already does), and/or enforce `validate-npm-package-name` on the resolved manifest name (close the scoped-name gap at `pickPackage.ts:753`) so the import target rejects a traversal name and re-asserts containment before any write.",
"severity": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H"
}
],
"references": [
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/security/advisories/GHSA-vq4v-j7r6-jq4m"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-82393"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/pull/12872"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/pull/12890"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/commit/51300fd41c5e4c8f47635108e373cc3d1f324fa7"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/commit/78e29fe5583a1e5d69ea05e414eff310f78d5ed9"
},
{
"type": "PACKAGE",
"url": "https://github.com/pnpm/pnpm"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/releases/tag/v10.34.5"
},
{
"type": "WEB",
"url": "https://github.com/pnpm/pnpm/releases/tag/v11.11.0"
}
]
}
12 changes: 6 additions & 6 deletions advisories/BREW-psutils-CVE-2023-36464.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"schema_version": "1.7.3",
"id": "BREW-psutils-CVE-2023-36464",
"published": "2026-08-13T17:29:24Z",
"modified": "2026-08-13T17:29:24Z",
"modified": "2026-09-03T09:55:21Z",
"upstream": [
"GHSA-4vvm-4w3v-6mr8",
"CVE-2023-36464",
Expand Down Expand Up @@ -34,7 +34,7 @@
"range_state": "fixed",
"upstream_fixed_in": "3.9.0",
"resource": "pypdf",
"resource_purl": "pkg:pypi/pypdf@6.15.0"
"resource_purl": "pkg:pypi/pypdf@6.16.2"
}
}
],
Expand All @@ -47,16 +47,16 @@
"strategy": "registry",
"ecosystem": "PyPI",
"name": "pypdf",
"subject_version": "6.15.0",
"key": "pkg:pypi/pypdf@6.15.0",
"subject_version": "6.16.2",
"key": "pkg:pypi/pypdf@6.16.2",
"resource": "pypdf"
},
{
"strategy": "registry",
"ecosystem": "PyPI",
"name": "pypdf",
"subject_version": "6.15.0",
"key": "pkg:pypi/pypdf@6.15.0",
"subject_version": "6.16.2",
"key": "pkg:pypi/pypdf@6.16.2",
"resource": "pypdf"
}
]
Expand Down
12 changes: 6 additions & 6 deletions advisories/BREW-psutils-CVE-2023-46250.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"schema_version": "1.7.3",
"id": "BREW-psutils-CVE-2023-46250",
"published": "2026-08-13T17:29:24Z",
"modified": "2026-08-13T17:29:24Z",
"modified": "2026-09-03T09:55:21Z",
"upstream": [
"GHSA-wjcc-cq79-p63f",
"CVE-2023-46250",
Expand Down Expand Up @@ -33,7 +33,7 @@
"range_state": "fixed",
"upstream_fixed_in": "3.17.0",
"resource": "pypdf",
"resource_purl": "pkg:pypi/pypdf@6.15.0"
"resource_purl": "pkg:pypi/pypdf@6.16.2"
}
}
],
Expand All @@ -46,16 +46,16 @@
"strategy": "registry",
"ecosystem": "PyPI",
"name": "pypdf",
"subject_version": "6.15.0",
"key": "pkg:pypi/pypdf@6.15.0",
"subject_version": "6.16.2",
"key": "pkg:pypi/pypdf@6.16.2",
"resource": "pypdf"
},
{
"strategy": "registry",
"ecosystem": "PyPI",
"name": "pypdf",
"subject_version": "6.15.0",
"key": "pkg:pypi/pypdf@6.15.0",
"subject_version": "6.16.2",
"key": "pkg:pypi/pypdf@6.16.2",
"resource": "pypdf"
}
]
Expand Down
12 changes: 6 additions & 6 deletions advisories/BREW-psutils-CVE-2025-55197.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"schema_version": "1.7.3",
"id": "BREW-psutils-CVE-2025-55197",
"published": "2026-08-13T17:29:24Z",
"modified": "2026-08-13T17:29:24Z",
"modified": "2026-09-03T09:55:21Z",
"upstream": [
"GHSA-7hfw-26vp-jp8m",
"CVE-2025-55197",
Expand Down Expand Up @@ -33,7 +33,7 @@
"range_state": "fixed",
"upstream_fixed_in": "6.0.0",
"resource": "pypdf",
"resource_purl": "pkg:pypi/pypdf@6.15.0"
"resource_purl": "pkg:pypi/pypdf@6.16.2"
}
}
],
Expand All @@ -46,16 +46,16 @@
"strategy": "registry",
"ecosystem": "PyPI",
"name": "pypdf",
"subject_version": "6.15.0",
"key": "pkg:pypi/pypdf@6.15.0",
"subject_version": "6.16.2",
"key": "pkg:pypi/pypdf@6.16.2",
"resource": "pypdf"
},
{
"strategy": "registry",
"ecosystem": "PyPI",
"name": "pypdf",
"subject_version": "6.15.0",
"key": "pkg:pypi/pypdf@6.15.0",
"subject_version": "6.16.2",
"key": "pkg:pypi/pypdf@6.16.2",
"resource": "pypdf"
}
]
Expand Down
Loading