Skip to content

Commit 1102616

Browse files
Invizoryianlancetaylor
authored andcommitted
cmd/go: fix command injection in VCS path
Fixes #23867, CVE-2018-7187 Change-Id: I5d0ba4923c9ed354ef76290e149c182447f9dfe2 Reviewed-on: https://go-review.googlesource.com/94656 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent c941e27 commit 1102616

File tree

2 files changed

+29
-45
lines changed

2 files changed

+29
-45
lines changed

src/cmd/go/internal/get/vcs.go

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ func repoRootForImportDynamic(importPath string, security web.SecurityMode) (*re
809809
}
810810
}
811811

812-
if err := validateRepoRootScheme(mmi.RepoRoot); err != nil {
812+
if err := validateRepoRoot(mmi.RepoRoot); err != nil {
813813
return nil, fmt.Errorf("%s: invalid repo root %q: %v", urlStr, mmi.RepoRoot, err)
814814
}
815815
rr := &repoRoot{
@@ -824,33 +824,16 @@ func repoRootForImportDynamic(importPath string, security web.SecurityMode) (*re
824824
return rr, nil
825825
}
826826

827-
// validateRepoRootScheme returns an error if repoRoot does not seem
828-
// to have a valid URL scheme. At this point we permit things that
829-
// aren't valid URLs, although later, if not using -insecure, we will
830-
// restrict repoRoots to be valid URLs. This is only because we've
831-
// historically permitted them, and people may depend on that.
832-
func validateRepoRootScheme(repoRoot string) error {
833-
end := strings.Index(repoRoot, "://")
834-
if end <= 0 {
835-
return errors.New("no scheme")
827+
// validateRepoRoot returns an error if repoRoot does not seem to be
828+
// a valid URL with scheme.
829+
func validateRepoRoot(repoRoot string) error {
830+
url, err := url.Parse(repoRoot)
831+
if err != nil {
832+
return err
836833
}
837-
838-
// RFC 3986 section 3.1.
839-
for i := 0; i < end; i++ {
840-
c := repoRoot[i]
841-
switch {
842-
case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
843-
// OK.
844-
case '0' <= c && c <= '9' || c == '+' || c == '-' || c == '.':
845-
// OK except at start.
846-
if i == 0 {
847-
return errors.New("invalid scheme")
848-
}
849-
default:
850-
return errors.New("invalid scheme")
851-
}
834+
if url.Scheme == "" {
835+
return errors.New("no scheme")
852836
}
853-
854837
return nil
855838
}
856839

src/cmd/go/internal/get/vcs_test.go

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -417,45 +417,46 @@ func TestMatchGoImport(t *testing.T) {
417417
}
418418
}
419419

420-
func TestValidateRepoRootScheme(t *testing.T) {
420+
func TestValidateRepoRoot(t *testing.T) {
421421
tests := []struct {
422422
root string
423-
err string
423+
ok bool
424424
}{
425425
{
426426
root: "",
427-
err: "no scheme",
427+
ok: false,
428428
},
429429
{
430430
root: "http://",
431-
err: "",
431+
ok: true,
432432
},
433433
{
434-
root: "a://",
435-
err: "",
434+
root: "git+ssh://",
435+
ok: true,
436436
},
437437
{
438-
root: "a#://",
439-
err: "invalid scheme",
438+
root: "http#://",
439+
ok: false,
440+
},
441+
{
442+
root: "-config",
443+
ok: false,
440444
},
441445
{
442446
root: "-config://",
443-
err: "invalid scheme",
447+
ok: false,
444448
},
445449
}
446450

447451
for _, test := range tests {
448-
err := validateRepoRootScheme(test.root)
449-
if err == nil {
450-
if test.err != "" {
451-
t.Errorf("validateRepoRootScheme(%q) = nil, want %q", test.root, test.err)
452-
}
453-
} else if test.err == "" {
454-
if err != nil {
455-
t.Errorf("validateRepoRootScheme(%q) = %q, want nil", test.root, test.err)
452+
err := validateRepoRoot(test.root)
453+
ok := err == nil
454+
if ok != test.ok {
455+
want := "error"
456+
if test.ok {
457+
want = "nil"
456458
}
457-
} else if err.Error() != test.err {
458-
t.Errorf("validateRepoRootScheme(%q) = %q, want %q", test.root, err, test.err)
459+
t.Errorf("validateRepoRoot(%q) = %q, want %s", test.root, err, want)
459460
}
460461
}
461462
}

0 commit comments

Comments
 (0)