[MM-64911] Ensure redirect URL is validated before redirecting (#33559) (#33596)

Automatic Merge
Этот коммит содержится в:
Mattermost Build
2025-07-31 09:34:00 +03:00
коммит произвёл GitHub
родитель 04d2ca2e3e
Коммит 8f6b6f1d0d
2 изменённых файлов: 59 добавлений и 9 удалений

Просмотреть файл

@@ -9,6 +9,7 @@ import (
"html"
"net/http"
"net/url"
"path"
"path/filepath"
"strings"
"time"
@@ -535,13 +536,48 @@ func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
}
func fullyQualifiedRedirectURL(siteURLPrefix, targetURL string) string {
parsed, _ := url.Parse(targetURL)
if parsed == nil || parsed.Scheme != "" || parsed.Host != "" {
return targetURL
parsed, err := url.Parse(targetURL)
if err != nil {
return siteURLPrefix
}
prefixParsed, err := url.Parse(siteURLPrefix)
if err != nil {
return siteURLPrefix
}
// Check if the targetURL is a valid URL and is within the siteURLPrefix
sameScheme := parsed.Scheme == prefixParsed.Scheme
sameHost := parsed.Host == prefixParsed.Host
safePath := strings.HasPrefix(path.Clean(parsed.Path), path.Clean(prefixParsed.Path))
if sameScheme && sameHost && safePath {
return targetURL
} else if parsed.Scheme != "" || parsed.Host != "" {
return siteURLPrefix
}
// For relative URLs, normalize and join with siteURLPrefix
if targetURL != "" && targetURL[0] != '/' {
targetURL = "/" + targetURL
}
return siteURLPrefix + targetURL
// Check for path traversal
joinedURL, err := url.JoinPath(siteURLPrefix, targetURL)
if err != nil {
return siteURLPrefix
}
unescapedURL, err := url.PathUnescape(joinedURL)
if err != nil {
return siteURLPrefix
}
parsed, err = url.Parse(unescapedURL)
if err != nil {
return siteURLPrefix
}
if !strings.HasPrefix(path.Clean(parsed.Path), path.Clean(prefixParsed.Path)) {
return siteURLPrefix
}
return parsed.String()
}