RoastMyOpsec

Vulnerabilities

Cargo.toml vs package.json on Production Origins

May 26, 2022

Cargo.toml vs package.json on production origins is two language manifests that must not sit next to index.html. /package.json donates npm names and versions. /Cargo.toml (and Cargo.lock) donates crate names, features, and pins — the same inventory class for Rust shops that published the crate root. Neither is a pentest. Both shrink reconnaissance and feed advisory lookups. crates.io is the public catalog. The marketing CDN is not. RoastMyOpsec probes /package.json with a bounded GET. It does not currently score /Cargo.toml, does not parse Cargo.lock on the URL scan, and does not fetch crates.

The practical difference

package.json is Node inventory. Cargo.toml is the crate manifest. Cargo.lock is the exact graph. go.mod is Go. Gemfile is Ruby. Dockerfile is how the image is built. .env is secrets.

A 200 on /Cargo.toml is an information leak even when every crate looks boring. Deny the names at the edge.

How to choose what to publish

CI: fail if Cargo.toml, Cargo.lock, package.json, or lockfiles appear in a static marketing artifact. App origins that must serve those files are rare — prefer not. CDN: deny those basenames. Keep Rust files in the private repo. Staging hostnames that are guessable get the same deny list.

FileTypical leakRoast todayTakeaway
/package.jsonnpm names and versionsBounded GETSee public package.json vs OSV
/Cargo.tomlCrate names and featuresNot scored; deny anywaySame class
/Cargo.lockExact crate graphNot scoredDeny the name
/.envLive secretsBounded signature GETSee .git vs .env

When Cargo.toml still wins (off the public origin)

It wins in a private repo and in CI. It never wins as a downloadable object on the marketing bucket. Pair with go.mod vs package.json if the same zip also shipped Go modules.

What the roast can prove

A reachable /package.json can surface. Cargo.toml is not a scored path. Confirm a 404 yourself. Pair with OSV lockfile deepen on a repo you own — that is a different channel than a URL roast.

Common mistakes

The first mistake is copying the whole crate to object storage because wasm-pack output lived next to Cargo.toml.

The second mistake is a path or git dependency in a public Cargo.toml that names an internal repo.

The third mistake is Disallow: /Cargo.toml and calling it access control.

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 now

FAQ

Is a public Cargo.toml a vulnerability?
It is an information leak. Remove it and deny the name. It is not always a credential dump, but it is not harmless.
Does RoastMyOpsec fetch Cargo.toml?
Not as a scored path today. It does probe /package.json. Deny Rust inventory filenames at the edge anyway.
Does Cargo.lock belong on the CDN?
No. Keep lockfiles in the private repo. Use OSV on a repo you own, not a marketing URL.

Sources

Related guides