Skip to content

cmd/go: develop safe-by-default API for calling VCS tools #77434

Description

@rolandshoemaker

When resolving CVE-2025-68119 (#77099), we made a minimal fix which converted all invocations of VCS commands to their safe form with as little other intervention as possible (directly associating flags with their values, making proper usage of constructs which separate flags from positional arguments, etc), but did not make a larger structural change.

We should replace the direct construction of VCS command arguments with an API which does this safe construction for the caller. This will prevent regressions if someone accidentally introduces a new flag/argument that violates the expected safe format we switched to.

The basic structure of this should be something like the following:

type vcsFlag struct {
	name string
	value string
}

// safeVCSCommand constructs an exec.Cmd for running a VCS command safely, preventing
// injection of flags or arguments that could alter its behavior in unintended ways.
//
// flags is a list of flag names and their values, which will be converted into
// a []string of flags in the form "--name=value" (or "-name=value" or another
// form based on the VCS being used).
//
// postFlagPositionalArgs is a list of positional arguments that should appear directly
// after flags, but before "--" (if supported by the VCS).
//
// positionalArgs is a list of positional arguments that should appear after "--".
func safeVCSCommand(cmd string, flags []vcsFlag, postFlagPositionalArgs, positionalArgs []string) *exec.Cmd

We would then replace all sites where we currently manually construct the flags/args with uses of this API.

We may want to not make it return an *exec.Cmd, and instead return a struct that can be passed to another function to execute the command, as there are a number of places where we pre-define the flag set and then use them to construct *exec.Cmds later.

cc @golang/security @jitsu-net

Metadata

Metadata

Assignees

No one assigned

    Labels

    GoCommandcmd/goNeedsFixThe path to resolution is known, but the work has not been done.SecurityToolProposalIssues describing a requested change to a Go tool or command-line program.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions