diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2023-09-15 17:59:42 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2023-09-18 08:32:09 +0300 |
commit | 671e6c405526c796fc54e0075a6e4245cd8bb4c7 (patch) | |
tree | 3ddc9880b178127b209f38f56634da9b3c224dc3 | |
parent | 929950811c6ad3d631784ea3c570051f1140c902 (diff) |
commit: Handle paths escaping the repository in RawBlame
When passing a path to git-blame(1) that would escape the repository
root it will return an error. Let's detect this early such that we can
gracefully return an `InvalidArgument` error.
-rw-r--r-- | internal/gitaly/service/commit/raw_blame.go | 6 | ||||
-rw-r--r-- | internal/gitaly/service/commit/raw_blame_test.go | 22 |
2 files changed, 28 insertions, 0 deletions
diff --git a/internal/gitaly/service/commit/raw_blame.go b/internal/gitaly/service/commit/raw_blame.go index 3ac61a742..09c1b8cc4 100644 --- a/internal/gitaly/service/commit/raw_blame.go +++ b/internal/gitaly/service/commit/raw_blame.go @@ -2,6 +2,7 @@ package commit import ( "fmt" + "path/filepath" "regexp" "strconv" "strings" @@ -101,6 +102,11 @@ func validateRawBlameRequest(locator storage.Locator, in *gitalypb.RawBlameReque return fmt.Errorf("empty Path") } + if !filepath.IsLocal(string(in.GetPath())) { + return structerr.NewInvalidArgument("path escapes repository root"). + WithMetadata("path", string(in.GetPath())) + } + blameRange := in.GetRange() if len(blameRange) > 0 && !validBlameRange.Match(blameRange) { return fmt.Errorf("invalid Range") diff --git a/internal/gitaly/service/commit/raw_blame_test.go b/internal/gitaly/service/commit/raw_blame_test.go index ce4e5b87d..cb0e5b76b 100644 --- a/internal/gitaly/service/commit/raw_blame_test.go +++ b/internal/gitaly/service/commit/raw_blame_test.go @@ -177,6 +177,28 @@ func TestRawBlame(t *testing.T) { }, }, { + desc: "path escapes repository root", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commit := gittest.WriteCommit(t, cfg, repoPath) + escapingPath := "im/gonna/../../../escape" + + return setupData{ + request: &gitalypb.RawBlameRequest{ + Repository: repo, + Revision: []byte(commit), + Path: []byte(escapingPath), + Range: []byte("1,1"), + }, + expectedErr: testhelper.ToInterceptedMetadata( + structerr.NewInvalidArgument("path escapes repository root"). + WithMetadata("path", escapingPath), + ), + } + }, + }, + { desc: "simple blame", setup: func(t *testing.T) setupData { repo, repoPath := gittest.CreateRepository(t, ctx, cfg) |