Skip to content

Commit 635e073

Browse files
authored
Merge branch 'main' into carterbrainerd-vuln-100-src-snapshot-run-allows-os-command-injection-via-malicious
2 parents f699739 + e6945cf commit 635e073

2 files changed

Lines changed: 14 additions & 12 deletions

File tree

internal/servegit/serve.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ func (s *Serve) handler() http.Handler {
102102
_ = enc.Encode(&resp)
103103
})
104104

105-
safeFS := http.FS(s.RootFS.FS())
106-
fs := http.FileServer(safeFS)
107105
svc := &Handler{
108106
Dir: func(_ context.Context, name string) (string, error) {
109107
return filepath.Join(s.Root, filepath.FromSlash(name)), nil
@@ -123,14 +121,17 @@ func (s *Serve) handler() http.Handler {
123121
RootFS: s.RootFS,
124122
}
125123
mux.Handle("/repos/", http.StripPrefix("/repos/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
126-
// Use git service if git is trying to clone. Otherwise show http.FileServer for convenience
124+
// Only serve the smart Git HTTP endpoints used for cloning/fetching.
125+
// We deliberately do not fall back to a file server: doing so would
126+
// expose arbitrary files under the served root to unauthenticated
127+
// clients (see VULN-99 / HackerOne #3814799).
127128
for _, suffix := range []string{"/info/refs", "/git-upload-pack"} {
128129
if strings.HasSuffix(r.URL.Path, suffix) {
129130
svc.ServeHTTP(w, r)
130131
return
131132
}
132133
}
133-
fs.ServeHTTP(w, r)
134+
http.NotFound(w, r)
134135
})))
135136

136137
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

internal/servegit/serve_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,15 @@ func testReposHandler(t *testing.T, h http.Handler, repos []Repo) {
9797
}
9898
}
9999

100-
// repos page will list the top-level dirs
101-
list := get("/repos/")
102-
for _, repo := range repos {
103-
if path.Dir(repo.URI) != "/repos" {
104-
continue
105-
}
106-
if !strings.Contains(repo.Name, "/") && !strings.Contains(list, repo.Name) {
107-
t.Errorf("repos page does not contain substring %q", repo.Name)
100+
// Directory browsing under /repos/ is intentionally disabled to avoid
101+
// exposing arbitrary files (VULN-99). Only smart Git HTTP endpoints are
102+
// served; anything else returns 404.
103+
if res, err := http.Get(ts.URL + "/repos/"); err != nil {
104+
t.Fatal(err)
105+
} else {
106+
res.Body.Close()
107+
if res.StatusCode != http.StatusNotFound {
108+
t.Errorf("GET /repos/ status = %d, want %d", res.StatusCode, http.StatusNotFound)
108109
}
109110
}
110111

0 commit comments

Comments
 (0)