Merge pull request #464 from stefanprodan/fix-store-path-traversal

Fix path traversal in `/store` endpoint
This commit is contained in:
Stefan Prodan
2026-03-14 15:08:52 +02:00
committed by GitHub
2 changed files with 35 additions and 0 deletions
+7
View File
@@ -7,11 +7,14 @@ import (
"net/http"
"os"
"path"
"regexp"
"github.com/gorilla/mux"
"go.uber.org/zap"
)
var validHash = regexp.MustCompile(`^[a-f0-9]{40}$`)
// Store godoc
// @Summary Upload file
// @Description writes the posted content to disk at /data/hash and returns the SHA1 hash of the content
@@ -54,6 +57,10 @@ func (s *Server) storeReadHandler(w http.ResponseWriter, r *http.Request) {
defer span.End()
hash := mux.Vars(r)["hash"]
if !validHash.MatchString(hash) {
s.ErrorResponse(w, r, span, "invalid hash", http.StatusBadRequest)
return
}
content, err := os.ReadFile(path.Join(s.config.DataPath, hash))
if err != nil {
s.logger.Warn("reading file failed", zap.Error(err), zap.String("file", path.Join(s.config.DataPath, hash)))
+28
View File
@@ -52,3 +52,31 @@ func TestStoreReadHandler_ContentType(t *testing.T) {
}
}
}
func TestStoreReadHandler_PathTraversal(t *testing.T) {
srv := NewMockServer()
srv.config.DataPath = t.TempDir()
traversalPaths := []string{
"../../../../etc/passwd",
"../../../etc/shadow",
"..%2f..%2f..%2fetc%2fpasswd",
"abc123",
"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzg", // 40 chars but not hex
}
for _, tp := range traversalPaths {
req, err := http.NewRequest("GET", "/store/"+tp, nil)
if err != nil {
t.Fatal(err)
}
req = mux.SetURLVars(req, map[string]string{"hash": tp})
rr := httptest.NewRecorder()
http.HandlerFunc(srv.storeReadHandler).ServeHTTP(rr, req)
if !strings.Contains(rr.Body.String(), "invalid hash") {
t.Errorf("path %q: expected 'invalid hash' error, got %q", tp, rr.Body.String())
}
}
}