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>
Этот коммит содержится в:
Agniva De Sarker
2020-11-10 13:06:59 +05:30
коммит произвёл GitHub
родитель 39b5b601f8
Коммит 0ca8cb36b4
6 изменённых файлов: 206 добавлений и 65 удалений

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

@@ -560,6 +560,8 @@ func TestPreparePostForClientWithImageProxy(t *testing.T) {
*cfg.ImageProxySettings.RemoteImageProxyOptions = "foo"
})
th.Server.ImageProxy = imageproxy.MakeImageProxy(th.Server, th.Server.HTTPService, th.Server.Log)
return th
}

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

@@ -16,6 +16,7 @@ import (
"github.com/mattermost/mattermost-server/v5/mlog"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/plugin/plugintest/mock"
"github.com/mattermost/mattermost-server/v5/services/imageproxy"
"github.com/mattermost/mattermost-server/v5/services/searchengine/mocks"
"github.com/mattermost/mattermost-server/v5/store/storetest"
storemocks "github.com/mattermost/mattermost-server/v5/store/storetest/mocks"
@@ -471,60 +472,71 @@ func TestImageProxy(t *testing.T) {
*cfg.ServiceSettings.SiteURL = "http://mymattermost.com"
})
th.Server.ImageProxy = imageproxy.MakeImageProxy(th.Server, th.Server.HTTPService, th.Server.Log)
for name, tc := range map[string]struct {
ProxyType string
ProxyURL string
ProxyOptions string
ImageURL string
ProxiedImageURL string
ProxyType string
ProxyURL string
ProxyOptions string
ImageURL string
ProxiedImageURL string
ProxiedRemovedImageURL string
}{
"atmos/camo": {
ProxyType: model.IMAGE_PROXY_TYPE_ATMOS_CAMO,
ProxyURL: "https://127.0.0.1",
ProxyOptions: "foo",
ImageURL: "http://mydomain.com/myimage",
ProxiedImageURL: "http://mymattermost.com/api/v4/image?url=http%3A%2F%2Fmydomain.com%2Fmyimage",
ProxyType: model.IMAGE_PROXY_TYPE_ATMOS_CAMO,
ProxyURL: "https://127.0.0.1",
ProxyOptions: "foo",
ImageURL: "http://mydomain.com/myimage",
ProxiedRemovedImageURL: "http://mydomain.com/myimage",
ProxiedImageURL: "http://mymattermost.com/api/v4/image?url=http%3A%2F%2Fmydomain.com%2Fmyimage",
},
"atmos/camo_SameSite": {
ProxyType: model.IMAGE_PROXY_TYPE_ATMOS_CAMO,
ProxyURL: "https://127.0.0.1",
ProxyOptions: "foo",
ImageURL: "http://mymattermost.com/myimage",
ProxiedImageURL: "http://mymattermost.com/myimage",
ProxyType: model.IMAGE_PROXY_TYPE_ATMOS_CAMO,
ProxyURL: "https://127.0.0.1",
ProxyOptions: "foo",
ImageURL: "http://mymattermost.com/myimage",
ProxiedRemovedImageURL: "http://mymattermost.com/myimage",
ProxiedImageURL: "http://mymattermost.com/myimage",
},
"atmos/camo_PathOnly": {
ProxyType: model.IMAGE_PROXY_TYPE_ATMOS_CAMO,
ProxyURL: "https://127.0.0.1",
ProxyOptions: "foo",
ImageURL: "/myimage",
ProxiedImageURL: "/myimage",
ProxyType: model.IMAGE_PROXY_TYPE_ATMOS_CAMO,
ProxyURL: "https://127.0.0.1",
ProxyOptions: "foo",
ImageURL: "/myimage",
ProxiedRemovedImageURL: "http://mymattermost.com/myimage",
ProxiedImageURL: "http://mymattermost.com/myimage",
},
"atmos/camo_EmptyImageURL": {
ProxyType: model.IMAGE_PROXY_TYPE_ATMOS_CAMO,
ProxyURL: "https://127.0.0.1",
ProxyOptions: "foo",
ImageURL: "",
ProxiedImageURL: "",
ProxyType: model.IMAGE_PROXY_TYPE_ATMOS_CAMO,
ProxyURL: "https://127.0.0.1",
ProxyOptions: "foo",
ImageURL: "",
ProxiedRemovedImageURL: "",
ProxiedImageURL: "",
},
"local": {
ProxyType: model.IMAGE_PROXY_TYPE_LOCAL,
ImageURL: "http://mydomain.com/myimage",
ProxiedImageURL: "http://mymattermost.com/api/v4/image?url=http%3A%2F%2Fmydomain.com%2Fmyimage",
ProxyType: model.IMAGE_PROXY_TYPE_LOCAL,
ImageURL: "http://mydomain.com/myimage",
ProxiedRemovedImageURL: "http://mydomain.com/myimage",
ProxiedImageURL: "http://mymattermost.com/api/v4/image?url=http%3A%2F%2Fmydomain.com%2Fmyimage",
},
"local_SameSite": {
ProxyType: model.IMAGE_PROXY_TYPE_LOCAL,
ImageURL: "http://mymattermost.com/myimage",
ProxiedImageURL: "http://mymattermost.com/myimage",
ProxyType: model.IMAGE_PROXY_TYPE_LOCAL,
ImageURL: "http://mymattermost.com/myimage",
ProxiedRemovedImageURL: "http://mymattermost.com/myimage",
ProxiedImageURL: "http://mymattermost.com/myimage",
},
"local_PathOnly": {
ProxyType: model.IMAGE_PROXY_TYPE_LOCAL,
ImageURL: "/myimage",
ProxiedImageURL: "/myimage",
ProxyType: model.IMAGE_PROXY_TYPE_LOCAL,
ImageURL: "/myimage",
ProxiedRemovedImageURL: "http://mymattermost.com/myimage",
ProxiedImageURL: "http://mymattermost.com/myimage",
},
"local_EmptyImageURL": {
ProxyType: model.IMAGE_PROXY_TYPE_LOCAL,
ImageURL: "",
ProxiedImageURL: "",
ProxyType: model.IMAGE_PROXY_TYPE_LOCAL,
ImageURL: "",
ProxiedRemovedImageURL: "",
ProxiedImageURL: "",
},
} {
t.Run(name, func(t *testing.T) {
@@ -547,14 +559,14 @@ func TestImageProxy(t *testing.T) {
assert.Equal(t, "![foo]("+tc.ImageURL+")", th.App.PostWithProxyRemovedFromImageURLs(post).Message)
post.Message = "![foo](" + tc.ProxiedImageURL + ")"
assert.Equal(t, "![foo]("+tc.ImageURL+")", th.App.PostWithProxyRemovedFromImageURLs(post).Message)
assert.Equal(t, "![foo]("+tc.ProxiedRemovedImageURL+")", th.App.PostWithProxyRemovedFromImageURLs(post).Message)
if tc.ImageURL != "" {
post.Message = "![foo](" + tc.ImageURL + " =500x200)"
assert.Equal(t, "![foo]("+tc.ProxiedImageURL+" =500x200)", th.App.PostWithProxyAddedToImageURLs(post).Message)
assert.Equal(t, "![foo]("+tc.ImageURL+" =500x200)", th.App.PostWithProxyRemovedFromImageURLs(post).Message)
post.Message = "![foo](" + tc.ProxiedImageURL + " =500x200)"
assert.Equal(t, "![foo]("+tc.ImageURL+" =500x200)", th.App.PostWithProxyRemovedFromImageURLs(post).Message)
assert.Equal(t, "![foo]("+tc.ProxiedRemovedImageURL+" =500x200)", th.App.PostWithProxyRemovedFromImageURLs(post).Message)
}
})
}
@@ -675,6 +687,8 @@ func TestCreatePost(t *testing.T) {
*cfg.ImageProxySettings.RemoteImageProxyOptions = "foo"
})
th.Server.ImageProxy = imageproxy.MakeImageProxy(th.Server, th.Server.HTTPService, th.Server.Log)
imageURL := "http://mydomain.com/myimage"
proxiedImageURL := "http://mymattermost.com/api/v4/image?url=http%3A%2F%2Fmydomain.com%2Fmyimage"
@@ -755,6 +769,8 @@ func TestPatchPost(t *testing.T) {
*cfg.ImageProxySettings.RemoteImageProxyOptions = "foo"
})
th.Server.ImageProxy = imageproxy.MakeImageProxy(th.Server, th.Server.HTTPService, th.Server.Log)
imageURL := "http://mydomain.com/myimage"
proxiedImageURL := "http://mymattermost.com/api/v4/image?url=http%3A%2F%2Fmydomain.com%2Fmyimage"
@@ -975,6 +991,8 @@ func TestUpdatePost(t *testing.T) {
*cfg.ImageProxySettings.RemoteImageProxyOptions = "foo"
})
th.Server.ImageProxy = imageproxy.MakeImageProxy(th.Server, th.Server.HTTPService, th.Server.Log)
imageURL := "http://mydomain.com/myimage"
proxiedImageURL := "http://mymattermost.com/api/v4/image?url=http%3A%2F%2Fmydomain.com%2Fmyimage"