From a31d7f028796acd85b8463493d7bbe5cf1c7d6b0 Mon Sep 17 00:00:00 2001 From: poyrazK <83272398+poyrazK@users.noreply.github.com> Date: Thu, 21 May 2026 13:41:02 +0300 Subject: [PATCH 1/3] fix: add path traversal validation in getBucketAndKeyRequired Reject keys containing '..' pattern to prevent path traversal attacks (e.g., '../../etc/passwd'). All handlers using this helper function are now protected. Fixes #683 --- internal/handlers/helper.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/internal/handlers/helper.go b/internal/handlers/helper.go index b231ae61d..f1236e031 100644 --- a/internal/handlers/helper.go +++ b/internal/handlers/helper.go @@ -2,6 +2,8 @@ package httphandlers import ( + "strings" + "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/poyrazk/thecloud/internal/errors" @@ -53,5 +55,11 @@ func getBucketAndKeyRequired(c *gin.Context) (bucket, key string, ok bool) { return "", "", false } + // Prevent path traversal attacks (e.g., "../../../etc/passwd") + if strings.Contains(key, "..") { + httputil.Error(c, errors.New(errors.InvalidInput, "invalid key")) + return "", "", false + } + return bucket, key, true } From bd6ca1668f6b8c973823c8176d9a7c6b480dc846 Mon Sep 17 00:00:00 2001 From: poyrazK <83272398+poyrazK@users.noreply.github.com> Date: Thu, 21 May 2026 13:49:00 +0300 Subject: [PATCH 2/3] fix: strengthen path traversal validation and add test coverage - Check for path separators (/ and \) in addition to ".." - Prevents encoded and mixed separator bypass attempts - Add test case for path traversal rejection Fixes #683 --- internal/handlers/helper.go | 2 +- internal/handlers/helper_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/internal/handlers/helper.go b/internal/handlers/helper.go index f1236e031..fe060544d 100644 --- a/internal/handlers/helper.go +++ b/internal/handlers/helper.go @@ -56,7 +56,7 @@ func getBucketAndKeyRequired(c *gin.Context) (bucket, key string, ok bool) { } // Prevent path traversal attacks (e.g., "../../../etc/passwd") - if strings.Contains(key, "..") { + if strings.Contains(key, "..") || strings.Contains(key, "/") || strings.Contains(key, "\\") { httputil.Error(c, errors.New(errors.InvalidInput, "invalid key")) return "", "", false } diff --git a/internal/handlers/helper_test.go b/internal/handlers/helper_test.go index 29363b01b..3f13d8889 100644 --- a/internal/handlers/helper_test.go +++ b/internal/handlers/helper_test.go @@ -120,4 +120,28 @@ func TestGetBucketAndKeyRequired(t *testing.T) { assert.Equal(t, http.StatusBadRequest, w.Code) assert.Contains(t, w.Body.String(), "key is required") }) + + t.Run("path traversal rejected", func(t *testing.T) { + traversalKeys := []string{ + "../etc/passwd", + "foo/../bar", + "foo\\..\\bar", + "foo/../../etc/passwd", + } + for _, key := range traversalKeys { + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + c.Params = []gin.Param{ + {Key: "bucket", Value: testBucket}, + {Key: "key", Value: key}, + } + + bucket, key, ok := getBucketAndKeyRequired(c) + + assert.False(t, ok, "key %q should be rejected", key) + assert.Empty(t, bucket) + assert.Empty(t, key) + assert.Equal(t, http.StatusBadRequest, w.Code) + } + }) } From a71ebf58b29ad38a120f43bf780570748ba51763 Mon Sep 17 00:00:00 2001 From: poyrazK <83272398+poyrazK@users.noreply.github.com> Date: Thu, 21 May 2026 15:04:32 +0300 Subject: [PATCH 3/3] fix: revert path separator check in path traversal validation The Gin glob pattern *key captures paths with leading /, so forward slashes in keys are normal. Revert to only checking for ".." pattern while adding clarifying comment. This fixes test failures in TestStorageHandlerUpload and other storage handler tests that use keys like "test.txt". --- internal/handlers/helper.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/handlers/helper.go b/internal/handlers/helper.go index fe060544d..45aaa4ac6 100644 --- a/internal/handlers/helper.go +++ b/internal/handlers/helper.go @@ -56,7 +56,8 @@ func getBucketAndKeyRequired(c *gin.Context) (bucket, key string, ok bool) { } // Prevent path traversal attacks (e.g., "../../../etc/passwd") - if strings.Contains(key, "..") || strings.Contains(key, "/") || strings.Contains(key, "\\") { + // Note: Gin glob pattern *key captures the path with leading /, so we only check for ".." + if strings.Contains(key, "..") { httputil.Error(c, errors.New(errors.InvalidInput, "invalid key")) return "", "", false }