Vulnerabilities
pnpm-lock.yaml vs package.json on Production Origins
March 12, 2025
pnpm-lock.yaml vs package.json on a production origin is two Node inventory files that do not belong next to index.html. /package.json is declared dependencies — the roast signatures it. pnpm-lock.yaml is the exact pnpm pin set, often more detailed. Serving either is the same class of miss as a leftover /package.json. RoastMyOpsec may not fetch pnpm-lock.yaml today. Still deny that name at the edge. Do not advertise lockfiles in robots.txt.
The practical difference
package.json is the short list. pnpm-lock.yaml is the resolved graph. Public pins help strangers prioritize known advisories against your stack. That work belongs in a private repo with Dependabot, not on the CDN.
A lockfile is not a secret by default. It is still not a marketing asset. Scripts and private registry package names make the leak worse. Keep the publish artifact to hashed front-end files.
How to choose based on what you shipped
CI: fail if package.json or pnpm-lock.yaml appear in the static artifact. CDN: deny those basenames. Advisories: run them on the repo you own, not by publishing the lockfile. If both files are public, remove both the same day.
| Option | When it wins | Watch-out | Takeaway |
|---|---|---|---|
| /package.json | Almost never on the CDN | Names, versions, scripts | Roast signatures this path today |
| /pnpm-lock.yaml | Never on the CDN | Resolved graph as a map | Same class of miss; deny the name |
| Lockfile in private CI | Reproducible installs and alerts | Do not rsync it to the bucket | Keep pins off the origin |
| robots.txt Disallow | Not for lockfiles | Treasure-map line | Edge deny is the control |
When each file wins (off the brochure origin)
package.json wins in git and on the registry. pnpm-lock.yaml wins in git and CI. Neither wins as a downloadable object on the production document root.
Yarn and npm lockfiles are the same decision in different filenames. Deny the family at the edge rather than playing allowlist bingo in robots.txt.
Common mistakes
The first mistake is 'pnpm is unusual so nobody will look for the lockfile' on a public URL.
The second mistake is blocking package.json and leaving pnpm-lock.yaml.
The third mistake is Disallowing the lockfile in robots.txt instead of denying it at the CDN.
What a URL roast can prove
The roast signatures /package.json. pnpm-lock.yaml is not a scored path today. Still deny it. No install from your origin, no exploit of a listed package. A pass on package.json is not a pass on every lockfile name.
Free audit the URL you own
RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.
Free audit nowFAQ
- Is a public pnpm-lock.yaml a vulnerability?
- It is an information leak. Remove it and deny the name. It is not the same as a remote exploit, and it is not appropriate on a marketing origin.
- Does RoastMyOpsec fetch pnpm-lock.yaml?
- Not as a scored path today. It does probe /package.json. Deny the pnpm lockfile at the CDN anyway. Same class of miss.
- Is the lockfile a secret?
- Usually it is inventory, not a password. Private registry names and embedded tokens are the exception — treat those as credential incidents.
Sources
Related guides
Vulnerabilities
Public package.json vs Lockfile Advisories on ProductionVulnerabilities
Dockerfile vs package.json on Production OriginsVulnerabilities
.env.example vs .env on Production Origins