diff --git a/github/repos_contents.go b/github/repos_contents.go index be58fd52f66..874a3277283 100644 --- a/github/repos_contents.go +++ b/github/repos_contents.go @@ -192,8 +192,15 @@ func (s *RepositoriesService) DownloadContentsWithMeta(ctx context.Context, owne // as possible, both result types will be returned but only one will contain a // value and the other will be nil. // +// Due to an auth vulnerability issue in the GitHub v3 API, ".." is not allowed +// to appear anywhere in the "path" or this method will return an error. +// // GitHub API docs: https://docs.github.com/en/rest/repos/contents#get-repository-content func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path string, opts *RepositoryContentGetOptions) (fileContent *RepositoryContent, directoryContent []*RepositoryContent, resp *Response, err error) { + if strings.Contains(path, "..") { + return nil, nil, nil, errors.New("path must not contain '..' due to auth vulnerability issue") + } + escapedPath := (&url.URL{Path: strings.TrimSuffix(path, "/")}).String() u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, escapedPath) u, err = addOptions(u, opts) diff --git a/github/repos_contents_test.go b/github/repos_contents_test.go index 29262ce2db1..295c21684cd 100644 --- a/github/repos_contents_test.go +++ b/github/repos_contents_test.go @@ -465,6 +465,20 @@ func TestRepositoriesService_GetContents_DirectoryWithSpaces(t *testing.T) { } } +func TestRepositoriesService_GetContents_PathWithParent(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + mux.HandleFunc("/repos/o/r/contents/some/../directory/file.go", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{}`) + }) + ctx := context.Background() + _, _, _, err := client.Repositories.GetContents(ctx, "o", "r", "some/../directory/file.go", &RepositoryContentGetOptions{}) + if err == nil { + t.Fatal("Repositories.GetContents expected error but got none") + } +} + func TestRepositoriesService_GetContents_DirectoryWithPlusChars(t *testing.T) { client, mux, _, teardown := setup() defer teardown()