3 ms·
I only see one that it avoids: domain names / URLs as import paths makes ownership much more clear, and slightly harder to achieve typo-squatting... sometimes.
by Groxx 5y ago
I only see one that it avoids: domain names / URLs as import paths makes ownership much more clear, and slightly harder to achieve typo-squatting... sometimes. And I do very much like this part of go modules, it also helps decentralize the whole system a fair bit. I sincerely hope it becomes the dominant package-name strategy in time.
But lets pick another that seems on the surface pretty likely to be mitigated: source for downloaded-version X not matching version X repo's source, under "Malicious update" with cargo's `--allow-dirty`. After all, goproxy pulls from git repos directly, right? There's no --dirty flag or anything to push random garbage.
That's still a problem! Git tags are mutable, as are git repositories as a whole. You can absolutely tag a malicious version, get it into goproxy, and then change or remove the tag and any associated commits. The goproxy doesn't even store the SHA for correctly-tagged versions, only the code and a checksum of the code it saved, so finding the commit that it originally pointed to can be difficult or impossible. You can download the module and read the code from that, but that's true of any non-binary dependency system. You can't publish a change to an already-published version, but that's true of cargo too (afaik) as well as most package hosts (afaik), though goproxy takes a minor technical step further to make that accident-resistant (or at least easily detectable. which is great, everyone should do that).
- verdverm 5y agoA module in Goproxy should be in the global SumDB, so if you are consulting that (the default), even if someone managed to get a retag in, it would fail the sumdb check. I suspect that Goproxy, by virtue of running Go under the hood, consults sumdb prior to adding to the proxy. As long as a tag was fetched once, I would expect that any changes would be caught. There are of course edge cases, such as custom domain go get hosts are not all kept in the GoProxy, but their content hash should be.
- Groxx 5y agoyeah - in many other dependency systems, you only get protection for versions you use, as those are in your lockfile. the public gosumdb helps prevent a few more cases of re-releasing something + you upgrading + pulling it from a different provider (... which is mostly relevant due to its more-distributed setup, if it treated goproxy as canonical it'd be unnecessary because it wouldn't contain that re-release), but not "downloaded module does not match repository". I do think the sumdb setup is worth others copying, it's relatively cheap to maintain and it does clamp down on some issues. It also makes it much harder to revoke things though, as you can't remove anything from it ever - after a couple versions, Go finally added "redacted" versions, but the need for that is partly a consequence of having the permanently-immutable sumdb + not having a canonical source. Unique self-inflicted pain -> unique workaround, though it's all relatively reasonable and I think a net benefit.
- verdverm 5y agoSigstore & Cosign are worth looking into as well. GoReleaser supports those for compiled binaries. SLSA is another https://sigstore.dev/ https://sigstore.dev/ https://slsa.dev/ https://slsa.dev/
- Groxx 5y agoThat seems like just code-signing? If so: yeah, definitely, that should be supported by every packaging system. And it's largely ridiculous that it isn't. It removes the need to trust the packaging-host, so it's no longer a giant target for exploits that can modify every package at once. Go, using domain names, is probably in the best position to take advantage of this, as it allows you to lean on domain ownership (and maybe even use the same ssl certificate) rather than having to trust-on-first-use or something.
- verdverm 5y agoCosign also has a global signature chain, so new signatures secure older entries. It uses Trillian iirc. I also think that anyone can come along and submit a signature for any project. So in that sense, you could get an entity that verifies and signs widely used packages. They could build trust over time and be relied upon to validate deps so you don't have to inspect every dep yourself. Granted it supports containers and binary blobs currently, but if you had a reproducible way to zip any repo, you could sign that.
- Groxx 5y agoYeah, definitely. A "X has read this and claims it is safe to use" certificate would be a huge boon in a lot of cases, and is automation-friendly. Then you could pick reviewers you trust, and find (or exclusively use) packages that are covered by them. I'd love it, "curators" can be significant contributors to an ecosystem.