MM-26425: Make URL parsing for image proxy more robust (#16197)
* MM-26425: Make URL parsing for image proxy more robust - We don't bypass protocol relative URLs. - We don't bypass hostnames with a similar prefix. https: //mattermost.atlassian.net/browse/MM-26425 ```release-note NONE ``` * fix tests and incorporate review comments * Handle opaque URLs * Fix path tests Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
39b5b601f8
Коммит
0ca8cb36b4
@@ -29,6 +29,7 @@ type ImageProxy struct {
|
||||
|
||||
Logger *mlog.Logger
|
||||
|
||||
siteURL *url.URL
|
||||
lock sync.RWMutex
|
||||
backend ImageProxyBackend
|
||||
}
|
||||
@@ -50,6 +51,11 @@ func MakeImageProxy(configService configservice.ConfigService, httpService https
|
||||
Logger: logger,
|
||||
}
|
||||
|
||||
// We deliberately ignore the error because it's from config.json.
|
||||
// The function returns a nil pointer in case of error, and we handle it when it's used.
|
||||
siteURL, _ := url.Parse(*configService.Config().ServiceSettings.SiteURL)
|
||||
proxy.siteURL = siteURL
|
||||
|
||||
proxy.configListenerId = proxy.ConfigService.AddConfigListener(proxy.OnConfigChange)
|
||||
|
||||
config := proxy.ConfigService.Config()
|
||||
@@ -118,15 +124,32 @@ func (proxy *ImageProxy) GetImageDirect(imageURL string) (io.ReadCloser, string,
|
||||
// GetProxiedImageURL takes the URL of an image and returns a URL that can be used to view that image through the
|
||||
// image proxy.
|
||||
func (proxy *ImageProxy) GetProxiedImageURL(imageURL string) string {
|
||||
return getProxiedImageURL(imageURL, *proxy.ConfigService.Config().ServiceSettings.SiteURL)
|
||||
}
|
||||
|
||||
func getProxiedImageURL(imageURL, siteURL string) string {
|
||||
if imageURL == "" || imageURL[0] == '/' || strings.HasPrefix(imageURL, siteURL) {
|
||||
if imageURL == "" || proxy.siteURL == nil {
|
||||
return imageURL
|
||||
}
|
||||
// Parse url, return siteURL in case of failure.
|
||||
// Also if the URL is opaque.
|
||||
parsedURL, err := url.Parse(imageURL)
|
||||
if err != nil || parsedURL.Opaque != "" {
|
||||
return proxy.siteURL.String()
|
||||
}
|
||||
// If host is same as siteURL host, return.
|
||||
if parsedURL.Host == proxy.siteURL.Host {
|
||||
return parsedURL.String()
|
||||
}
|
||||
|
||||
return siteURL + "/api/v4/image?url=" + url.QueryEscape(imageURL)
|
||||
// Handle protocol-relative URLs.
|
||||
if parsedURL.Scheme == "" {
|
||||
parsedURL.Scheme = proxy.siteURL.Scheme
|
||||
}
|
||||
|
||||
// If it's a relative URL, fill up the hostname and return.
|
||||
if parsedURL.Host == "" {
|
||||
parsedURL.Host = proxy.siteURL.Host
|
||||
return parsedURL.String()
|
||||
}
|
||||
|
||||
return proxy.siteURL.String() + "/api/v4/image?url=" + url.QueryEscape(parsedURL.String())
|
||||
}
|
||||
|
||||
// GetUnproxiedImageURL takes the URL of an image on the image proxy and returns the original URL of the image.
|
||||
|
||||
Ссылка в новой задаче
Block a user