RoastMyOpsec

Vulnerabilities

pubspec.yaml vs package.json on Production Origins

May 19, 2025

pubspec.yaml 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. /pubspec.yaml (and pubspec.lock) donates Dart and Flutter package names, SDK constraints, and pins — the same inventory class for shops that published the project root next to a web build. Neither is a pentest. Both shrink reconnaissance and feed advisory lookups. pub.dev is the public catalog. The marketing CDN is not. RoastMyOpsec probes /package.json with a bounded GET. It does not currently score /pubspec.yaml, does not parse pubspec.lock on the URL scan, and does not fetch packages.

The practical difference

package.json is Node inventory. pubspec.yaml is the Dart/Flutter manifest. pubspec.lock is the exact graph. Cargo.toml is Rust. go.mod is Go. .env is secrets.

A 200 on /pubspec.yaml is an information leak even when every dependency looks boring. Deny the names at the edge.

How to choose what to publish

CI: fail if pubspec.yaml, pubspec.lock, package.json, or lockfiles appear in a static marketing artifact. Flutter web output should be the build/, not the repo root. CDN: deny those basenames. Keep Dart 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
/pubspec.yamlDart/Flutter depsNot scored; deny anywaySame class
/pubspec.lockExact package graphNot scoredDeny the name
/.envLive secretsBounded signature GETSee .git vs .env

When pubspec.yaml 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 Cargo.toml vs package.json if the same zip also shipped a Rust crate.

What the roast can prove

A reachable /package.json can surface. pubspec.yaml 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 uploading the Flutter project root because flutter build web lived next to pubspec.yaml.

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

The third mistake is Disallow: /pubspec.yaml 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 pubspec.yaml 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 pubspec.yaml?
Not as a scored path today. It does probe /package.json. Deny Dart inventory filenames at the edge anyway.
Does pubspec.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