Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
proposal: cmd/go: allow users to control VCS usage #41730
The go command runs commands like git and hg to download modules. In the past, we have had problems with security bugs in version control systems becoming security bugs in “go get”.
The original modules draft design removed use of these commands entirely, saying:
The removal of these commands was not possible in the end: being able to fetch directly from Git repos is too important, especially for closed source. But the security exposure has not gone away. We remain vulnerable to problems in VCS systems, especially the less scrutinized ones.
I propose to add a new GOVCS setting that controls which version control systems are allowed to be used for downloads.
In its simplest form, GOVCS is a pipe-separated list of allowed version control systems:
The set of all known version control systems can be abbreviated “all’:
The set of no VCS systems can be written “off”:
A glob pattern (already used for GOPRIVATE, GONOPROXY, and so on) followed by a colon can restrict the effect to a particular (module or import) path prefix:
The special pattern “private” means any pattern from GOPRIVATE.
A comma-separated list of restricted can be given. The first match in the list applies:
Finally, there is a default setting in the go command itself. An explicit setting of GOVCS takes priority but does not remove the defaults; the effect is as if the explicit GOVCS setting were inserted ahead of the defaults in the comma-separated list.
(Note that this gives considerably more control over exactly when a VCS can be used than the current behavior of “if it’s in the PATH, it can be used.”)
I propose the default GOVCS setting allow all VCS for private modules but only Git and Mercurial for public modules.
That is, the default setting is equivalent to:
The rationale behind allowing only Git and Mercurial is that these two systems have had the most attention to issues of being run as clients of untrusted servers. In contrast, Bazaar, Fossil, and Subversion have primarily been used in trusted, authenticated environments and are not as well scrutinized as attack surfaces.
It is certainly the case that even Git and Mercurial are unfortunately not free of bugs either, but those projects have had more scrutiny and have established a record of fixing them quickly.
The rationale behind allowing
Users who want to allow all VCS even for public source code servers would use
I propose that the public Go module mirror proxy.golang.org continue to allow all VCS.
It is already the case that the Go module mirror handles fetching Bazaar, Fossil, and Subversion repos for the vast majority of Go users: those users do not even need to install the corresponding binaries, and it is likely that most do not.
The module mirror also invokes the
The combination of disallowing less-popular version control systems by default but continuing to be able to fetch them through module mirrors balances improving baseline security on developer systems machines while not fragmenting the ecosystem.
This default does put the module mirror on the critical path for downloads of public Bazaar/Fossil/Subversion downloads, but it is the same system that serves the checksum database, which is already on the critical path for all downloads. And the setting that opts out of the checksum database and proxy for all modules—
Strong support. This would significantly reduce the attack surface of "go get".
I think the proposal could make the relative priority of comma and pipe more clear, but it looks like there is only one reasonable interpretation.
Once this is implemented, I think we should consider vulnerabilities in any VCS other than Git and Mercurial as out of scope for golang.org/security.
This is a step in the right direction, however I agree with the original "We want to move away from invoking version control tools".
In other programming languages, like say, Ruby, the equivalent of go modules is distributed as special purpose archives, like .gem files for Ruby. Go should allow something similar with a go module pack command that packs your module foo v1.2.3 to such an archive, maybe named firstname.lastname@example.org, which go get then can download over https, based on the go.mod file.
@beoran, we already support a protocol that does not need to invoke any version control tools. The
I presume that under this proposal,