repo: ignore unintended Git options for diff preview (#7871)

## Describe the pull request

Fixes
https://github.com/gogs/gogs/security/advisories/GHSA-9pp6-wq8c-3w2c
pull/7872/head
Joe Chen 2024-12-22 15:59:03 -05:00 committed by GitHub
parent 77a4a945ae
commit 68b3c8f339
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 9 additions and 7 deletions

View File

@ -119,7 +119,7 @@ type UpdateRepoFileOptions struct {
// UpdateRepoFile adds or updates a file in repository. // UpdateRepoFile adds or updates a file in repository.
func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (err error) { func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (err error) {
// 🚨 SECURITY: Prevent uploading files into the ".git" directory // 🚨 SECURITY: Prevent uploading files into the ".git" directory.
if isRepositoryGitPath(opts.NewTreeName) { if isRepositoryGitPath(opts.NewTreeName) {
return errors.Errorf("bad tree path %q", opts.NewTreeName) return errors.Errorf("bad tree path %q", opts.NewTreeName)
} }
@ -220,7 +220,7 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
// GetDiffPreview produces and returns diff result of a file which is not yet committed. // GetDiffPreview produces and returns diff result of a file which is not yet committed.
func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *gitutil.Diff, err error) { func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *gitutil.Diff, err error) {
// 🚨 SECURITY: Prevent uploading files into the ".git" directory // 🚨 SECURITY: Prevent uploading files into the ".git" directory.
if isRepositoryGitPath(treePath) { if isRepositoryGitPath(treePath) {
return nil, errors.Errorf("bad tree path %q", treePath) return nil, errors.Errorf("bad tree path %q", treePath)
} }
@ -243,7 +243,8 @@ func (repo *Repository) GetDiffPreview(branch, treePath, content string) (diff *
return nil, fmt.Errorf("write file: %v", err) return nil, fmt.Errorf("write file: %v", err)
} }
cmd := exec.Command("git", "diff", treePath) // 🚨 SECURITY: Prevent including unintended options in the path to the git command.
cmd := exec.Command("git", "diff", "--end-of-options", treePath)
cmd.Dir = localPath cmd.Dir = localPath
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
@ -288,7 +289,7 @@ type DeleteRepoFileOptions struct {
} }
func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (err error) { func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (err error) {
// 🚨 SECURITY: Prevent uploading files into the ".git" directory // 🚨 SECURITY: Prevent uploading files into the ".git" directory.
if isRepositoryGitPath(opts.TreePath) { if isRepositoryGitPath(opts.TreePath) {
return errors.Errorf("bad tree path %q", opts.TreePath) return errors.Errorf("bad tree path %q", opts.TreePath)
} }
@ -513,7 +514,7 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
return nil return nil
} }
// 🚨 SECURITY: Prevent uploading files into the ".git" directory // 🚨 SECURITY: Prevent uploading files into the ".git" directory.
if isRepositoryGitPath(opts.TreePath) { if isRepositoryGitPath(opts.TreePath) {
return errors.Errorf("bad tree path %q", opts.TreePath) return errors.Errorf("bad tree path %q", opts.TreePath)
} }
@ -554,7 +555,7 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
// 🚨 SECURITY: Prevent path traversal. // 🚨 SECURITY: Prevent path traversal.
upload.Name = pathutil.Clean(upload.Name) upload.Name = pathutil.Clean(upload.Name)
// 🚨 SECURITY: Prevent uploading files into the ".git" directory // 🚨 SECURITY: Prevent uploading files into the ".git" directory.
if isRepositoryGitPath(upload.Name) { if isRepositoryGitPath(upload.Name) {
continue continue
} }

View File

@ -302,7 +302,8 @@ func NewFilePost(c *context.Context, f form.EditRepoFile) {
} }
func DiffPreviewPost(c *context.Context, f form.EditPreviewDiff) { func DiffPreviewPost(c *context.Context, f form.EditPreviewDiff) {
treePath := c.Repo.TreePath // 🚨 SECURITY: Prevent path traversal.
treePath := pathutil.Clean(c.Repo.TreePath)
entry, err := c.Repo.Commit.TreeEntry(treePath) entry, err := c.Repo.Commit.TreeEntry(treePath)
if err != nil { if err != nil {