返回 DeepSeek-Reasonix
lsremote_injection_test.go
根目录 / internal / plugin / lsremote_injection_test.go
1 package plugin
2
3 import (
4 "context"
5 "os"
6 "os/exec"
7 "path/filepath"
8 "runtime"
9 "testing"
10 "time"
11 )
12
13 // The git locator is resolved before the launch is approved, and its
14 // repository part is attacker-controlled: a value that is not a network URL —
15 // starting with '-', or naming a local transport — must be rejected, never
16 // passed to ls-remote as an option or a path.
17 func TestGitLocatorRejectsNonURLRemotes(t *testing.T) {
18 if runtime.GOOS == "windows" {
19 t.Skip("POSIX payload")
20 }
21 if _, err := exec.LookPath("git"); err != nil {
22 t.Skip("git not installed")
23 }
24 dir := t.TempDir()
25 marker := filepath.Join(dir, "executed")
26 payload := filepath.Join(dir, "p.sh")
27 if err := os.WriteFile(payload, []byte("#!/bin/sh\necho ran >> '"+marker+"'\nexit 1\n"), 0o755); err != nil {
28 t.Fatal(err)
29 }
30 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
31 defer cancel()
32 for _, locator := range []string{
33 "git+--upload-pack=" + payload + " x@main",
34 "git+ext::" + payload + "@main",
35 "git+/tmp/local/repo.git@main",
36 } {
37 if _, _, err := resolveGitLocator(ctx, Spec{Name: "probe"}, locator); err == nil {
38 t.Fatalf("resolveGitLocator(%q) succeeded, want a rejected non-URL remote", locator)
39 }
40 }
41 if _, statErr := os.Stat(marker); statErr == nil {
42 t.Fatal("ls-remote ran a program named by the launcher locator")
43 }
44 }
45
46 func TestGitRemoteSchemeIsCaseInsensitiveAndRefusesHTTP(t *testing.T) {
47 for remote, want := range map[string]bool{
48 "https://example.test/r.git": true, "HTTPS://example.test/r.git": true, "Ssh://h/r.git": true, "git://h/r.git": true,
49 "http://example.test/r.git": false, "/srv/r.git": false, "file:///srv/r.git": false, "--upload-pack=x": false,
50 } {
51 if got := gitRemoteScheme.MatchString(remote); got != want {
52 t.Fatalf("gitRemoteScheme(%q) = %v, want %v", remote, got, want)
53 }
54 }
55 }
56
56 lines GO