From d86f0a280a702b2944df6b534219cb9ada3a01a4 Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Thu, 7 Apr 2022 05:42:15 +0100 Subject: [PATCH] libgit2: validate URL max length The major Git SaaS providers have repository URLs for both HTTP and SSH that tops around 250 characters in length. The limits chosen were a lot higher to align with use cases in which users may have on-premise servers with long domain names and paths. For SSH the validation is around path length only, which is now limited to 4096 characters, which is at the higher end of the range in Linux. For HTTP the validation is around the full URL provided by the caller. Signed-off-by: Paulo Gomes --- pkg/git/libgit2/managed/http.go | 4 ++++ pkg/git/libgit2/managed/ssh.go | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/pkg/git/libgit2/managed/http.go b/pkg/git/libgit2/managed/http.go index 04e1c54b..8a58dbb8 100644 --- a/pkg/git/libgit2/managed/http.go +++ b/pkg/git/libgit2/managed/http.go @@ -171,6 +171,10 @@ func createClientRequest(targetUrl string, action git2go.SmartServiceAction, t * } } + if len(finalUrl) > 2048 { + return nil, nil, fmt.Errorf("URL exceeds the max length (2048)") + } + client := &http.Client{ Transport: t, Timeout: fullHttpClientTimeOut, diff --git a/pkg/git/libgit2/managed/ssh.go b/pkg/git/libgit2/managed/ssh.go index 4c1f781d..d6272e85 100644 --- a/pkg/git/libgit2/managed/ssh.go +++ b/pkg/git/libgit2/managed/ssh.go @@ -125,12 +125,19 @@ func (t *sshSmartSubtransport) Action(urlString string, action git2go.SmartServi return nil, err } - // Escape \ and '. - uPath := strings.Replace(u.Path, `\`, `\\`, -1) - uPath = strings.Replace(uPath, `'`, `\'`, -1) + if len(u.Path) > 4096 { + return nil, fmt.Errorf("path exceeds the max length (4096)") + } - // TODO: Add percentage decode similar to libgit2. - // Refer: https://github.com/libgit2/libgit2/blob/358a60e1b46000ea99ef10b4dd709e92f75ff74b/src/str.c#L455-L481 + // decode URI's path + uPath, err := url.PathUnescape(u.Path) + if err != nil { + return nil, err + } + + // Escape \ and '. + uPath = strings.Replace(uPath, `\`, `\\`, -1) + uPath = strings.Replace(uPath, `'`, `\'`, -1) var cmd string switch action {