Skip to content

cmd/go: allow users to control VCS usage #41730

@rsc

Description

@rsc

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:

We want to move away from invoking version control tools such as bzr, fossil, git, hg, and svn to download source code. These fragment the ecosystem: packages developed using Bazaar or Fossil, for example, are effectively unavailable to users who cannot or choose not to install these tools. The version control tools have also been a source of exciting security problems. It would be good to move them outside the security perimeter.

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:

GOVCS=bzr|fossil|git|hg|svn  # any known VCS system

The set of all known version control systems can be abbreviated “all’:

GOVCS=all  # any known VCS system

The set of no VCS systems can be written “off”:

GOVCS=off  # no VCS usage allowed at all

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:

GOVCS=github.com:git  # on github.com, only use git

The special pattern “private” means any pattern from GOPRIVATE.
The special pattern “public” means anything not matched by GOPRIVATE.

A comma-separated list of restricted can be given. The first match in the list applies:

GOVCS=github.com:git,bitbucket.com:git|hg

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:

GOVCS=private:all,public:git|hg

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 private:all is that private servers are trusted. It is beyond the go command’s threat model to guard against scenarios in which a company’s private source code host has already been compromised.

Users who want to allow all VCS even for public source code servers would use

GOVCS=private:all,public:all

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 go command and its subprocesses in a security sandbox for added security, so it is more equipped to deal with potential compromises of the version control tools. It would simply run with GOVCS=public:all to continue allowing all the VCS tools to be used. We would encourage alternate module mirrors to do the same.

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—GOPRIVATE=*—would automatically opt out of the VCS restrictions as well.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions