Skip to main content

Payload CMS

Verified baseline scan — CVE Lite CLI v1.22.0 · 2026-06-12

Payload CMS logo

Summary

  • Project: Payload CMS — TypeScript-first headless CMS and application framework
  • Revision: eb5708b3d3834a50a29f19d93df7406011e08114
  • Lockfile: pnpm-lock.yaml (2,602 resolved packages, pnpm workspace monorepo)
  • Baseline findings: 18 unique vulnerable packages (1 critical · 7 high · 9 medium · 1 low)
  • OSV advisory matches: 36 CVE/advisory entries deduplicated into 18 packages
  • Direct vs transitive: 1 direct / 17 transitive
  • Validated fix command groups generated: 2
  • pnpm audit (same lockfile): 42 vulnerability entries (1 critical · 12 high · 26 moderate · 3 low)
  • Remediation applied in this study: workspace-scoped drizzle-orm remediation attempt and verification rescan

What this case study demonstrates

Payload CMS is a large pnpm workspace monorepo containing the core CMS, database adapters, testing infrastructure, examples, and deployment tooling. At 2,602 resolved packages, it represents a realistic modern JavaScript dependency graph where most risk originates from transitive dependencies rather than application runtime code.

The direct/transitive split (1 direct, 17 transitive) is the first thing worth noticing. Only one vulnerable package (drizzle-orm) is directly controlled by the project. The remaining findings arrive through build tooling, SDKs, framework integrations, and development dependencies. A developer running pnpm audit on this lockfile sees 42 vulnerability entries with no direct/transitive breakdown and no copy-and-run fix plan. CVE Lite surfaces 18 unique vulnerable packages, 2 command groups, and a clear split between what is directly fixable and what requires parent-chain decisions.

The most important findings are:

[email protected] — high, direct. CVE Lite generates a validated workspace-scoped upgrade command targeting the exact workspaces that depend on the package. This is the one finding Payload's maintainers directly control at the manifest level.

[email protected] — critical, transitive. CVE Lite identifies a fixed version but cannot safely generate an automated parent-upgrade path. This is an example of a finding that requires manual dependency-chain investigation.

[email protected] — high, transitive. A validated parent-upgrade path exists through wrangler. CVE Lite generates the specific pnpm add [email protected] command rather than suggesting a direct install of the transitive package.

Unlike raw advisory feeds, CVE Lite identifies a clear distinction between direct fixes, parent upgrades, and findings that require upstream dependency-chain investigation.


Comparison Note: CVE Lite CLI vs pnpm audit

Both tools were run against the same pnpm-lock.yaml on the same machine on 2026-06-12.

Metricpnpm auditCVE Lite CLI
Total reported findings4218
Critical11
High127
Moderate / Medium269
Low31
Direct vs transitive breakdown✓ (1 / 17)
Deduplicated package view
Validated fix targets
Parent-upgrade guidance
Copy-and-run commands✓ (2 groups)
Skipped findings with reason

Why the totals differ

pnpm audit reports vulnerability entries. A single vulnerable package may appear multiple times across advisory IDs and dependency paths.

CVE Lite reports unique vulnerable package versions and groups advisory data around actionable remediation decisions.

This explains the difference between 42 vulnerability entries and 18 vulnerable packages.

drizzle-orm is a concrete example. On this lockfile, pnpm audit reports multiple separate entries for the same package version across different workspace paths. CVE Lite deduplicates these into one high finding for [email protected] with a single consolidated workspace-scoped fix command — a clearer picture of how many package-level decisions are actually required.

Fix guidance differs materially:

pnpm audit --fix was attempted in an isolated copy of this lockfile. The workspace-scoped nature of the monorepo means automatic fix behavior may differ from what pnpm audit suggests.

CVE Lite generates validated commands without requiring assumptions about workspace layout:

pnpm add --filter ./packages/db-d1-sqlite --filter ./packages/db-postgres --filter ./packages/db-sqlite --filter ./packages/db-vercel-postgres --filter ./packages/drizzle --filter ./test [email protected]

For the critical finding, CVE Lite names fast-xml-parser as requiring manual chain investigation rather than suggesting a direct install of the transitive package.


Before vs After

A remediation attempt was performed using the generated workspace-scoped drizzle-orm upgrade command.

StageFindingsCriticalHighMediumLowDirectTransitiveCommand groups
Baseline (verified)1817911172
After remediation attempt1817911172

The generated remediation command completed successfully but did not reduce the finding count. The vulnerable [email protected] version remained present in the dependency graph.

This illustrates a common monorepo reality: upgrading a dependency in selected workspaces does not always eliminate every vulnerable path present in the lockfile. Partial coverage is a documented limitation of workspace-scoped remediation commands, and rescanning after every command group is the correct workflow.


Fix Journey

The scanner generated two remediation groups.

Group 1 — direct workspace remediation

pnpm add --filter ./packages/db-d1-sqlite --filter ./packages/db-postgres --filter ./packages/db-sqlite --filter ./packages/db-vercel-postgres --filter ./packages/drizzle --filter ./test [email protected]

This command targets the workspaces that depend on drizzle-orm directly. CVE Lite identifies the exact --filter paths rather than applying a root-level upgrade, which preserves workspace isolation.

Group 2 — parent upgrades

These upgrades address findings through dependency-parent relationships rather than direct package replacement. The wrangler upgrade resolves the [email protected] finding. The @sentry/nextjs, @swc/cli, and lint-staged upgrades address several medium transitive findings through their resolved dependency trees.

Critical finding

[email protected] remains unresolved. The scanner identified a fixed version but could not generate a safe parent-upgrade recommendation automatically. This is an example of a finding that requires manual dependency-chain investigation — identifying which workspace or toolchain package pulls in fast-xml-parser and whether a newer version of that parent resolves the transitive dependency.

The distinction between Group 1's direct workspace scoping and Group 2's parent upgrades is intentional. The first replaces a package Payload controls. The second upgrades parents to pull in safer transitive versions. Neither covers fast-xml-parser because no safe automated path was identified.


Why this matters

Payload CMS is a widely used TypeScript-first headless CMS adopted across production applications. Its monorepo is professionally maintained, typed end-to-end, and ships on a regular cadence. Yet a verified lockfile scan still surfaces 18 vulnerable packages — 17 of them transitive.

That pattern is consistent across every modern framework monorepo scan in this project: the risk is not in application runtime code. It is in the toolchain developers install, trust, and rarely audit — ORM adapters, observability SDKs, deployment tools, linting stacks, and testing infrastructure.

Two chains in this scan are worth naming specifically:

wrangler[email protected] (high). A developer auditing "my Payload site dependencies" would not immediately associate a Cloudflare deployment tool with an HTTP client vulnerability. CVE Lite names the parent chain and generates the upgrade command directly.

[email protected] (critical, transitive). The critical finding arrives through a transitive path with no auto-generated fix. This is the operationally correct outcome — surfacing the finding with an honest assessment of what can and cannot be automated, rather than generating a command that might introduce breakage.

For a team doing a pre-release check, the operationally useful question is not "how many advisories exist?" It is "what do I run right now, and what needs upstream?" CVE Lite answers that in under 30 seconds: two command groups for the confident first pass, one critical finding flagged for manual investigation, and remaining entries explaining why the rest are not auto-fixable.


Scan command

Run from the Payload CMS repository root or from the examples/payload directory in this repository:

cve-lite . --verbose --all

The example lockfile in this repository reflects Payload CMS at revision eb5708b3d3834a50a29f19d93df7406011e08114. Payload releases frequently — and OSV advisory data changes over time — so re-scanning may show a different finding count even on the same lockfile revision.


Scan verification

Every number in this case study comes from a live scan of the committed fixture at examples/payload/ in the CVE Lite CLI repository.

FieldValue
Scan date2026-06-12
CLI versionv1.22.0
CVE Lite commandnpx cve-lite-cli . --verbose --all
pnpm audit commandpnpm audit
Advisory sourceOSV (https://api.osv.dev) — online mode
Lockfile sourceexamples/payload/pnpm-lock.yaml from payloadcms/payload@eb5708b
Packages parsed (CVE Lite)2,602
Unique vulnerable packages (CVE Lite)18
Vulnerability entries (pnpm audit)42
Fix command groups (CVE Lite)2

Reproduce CVE Lite locally from the repository root:

npm install
npx tsx src/index.ts examples/payload --verbose --all

Reproduce pnpm audit from the example directory (Node.js 22+ recommended):

cd examples/payload
pnpm audit
pnpm audit --json

Both tools were run against the same pnpm-lock.yaml on the same machine on 2026-06-12.


Remaining risk

All 18 findings remain present after the remediation attempt.

  • 1 critical: [email protected] (transitive — no auto parent upgrade)
  • 7 high: including drizzle-orm, undici, rollup, effect, and others via toolchain paths
  • 9 medium: including file-type, yaml, postcss, uuid, and related build/SDK packages
  • 1 low: transitive finding via a development dependency chain

Baseline findings

The verified scan surfaced 18 vulnerable packages:

Critical

High

Medium

Low

  • One transitive low-severity finding

Want your project reviewed?

If you maintain an interesting JavaScript or TypeScript project and want CVE Lite CLI considered for a public case study, open an issue in the CVE Lite CLI repository.

Please include:

  • the repository link
  • why the project would make a useful case study
  • whether the dependency graph is publicly reproducible

Not every project will be selected. Preference will go to projects that are publicly useful, technically interesting, and strong examples of realistic dependency remediation workflows.