RoastMyOpsec

Vulnerabilities

go.mod vs package.json on Production Origins

January 12, 2024

go.mod 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. /go.mod (and go.sum) donates module paths, Go version, and require pins — the same inventory class for Go shops that accidentally published the repo root. Neither is a pentest. Both shrink reconnaissance and feed advisory lookups. The public module proxy is the catalog. The marketing CDN is not. RoastMyOpsec probes /package.json with a bounded GET. It does not currently score /go.mod, does not parse go.sum on the URL scan, and does not download modules.

The practical difference

package.json is Node inventory. go.mod is the module file. go.sum is the checksum lock. Gemfile is Ruby. requirements.txt is Python. Dockerfile is how the image is built. .env is secrets.

A 200 on /go.mod is an information leak even when every require looks boring. Deny the names at the edge.

How to choose what to publish

CI: fail if go.mod, go.sum, 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 Go 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
/go.modModule path and requiresNot scored; deny anywaySame class
/go.sumChecksum graphNot scoredDeny the name
/.envLive secretsBounded signature GETSee .git vs .env

When go.mod 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 Dockerfile vs package.json if the same zip also shipped a container recipe.

What the roast can prove

A reachable /package.json can surface. go.mod 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 Go module to object storage because embed lived next to go.mod.

The second mistake is a replace directive in a public go.mod that names an internal path.

The third mistake is Disallow: /go.mod 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 go.mod 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 go.mod?
Not as a scored path today. It does probe /package.json. Deny Go inventory filenames at the edge anyway.
Does go.sum belong on the CDN?
No. Keep checksum files in the private repo. Use OSV on a repo you own, not a marketing URL.

Sources

Related guides