Restrict post metadata to allow for potentially unsafe links (#26098)

* Restrict post metadata to allow for potentially unsafe links

* Enhance tests to test tests.

* Restrict prop to only be active if set to 'true'

* Adress feedback.

* Fix existing test using invalid permalink.

* Fix more tests
Этот коммит содержится в:
Christopher Speller
2024-02-22 13:31:24 -08:00
коммит произвёл GitHub
родитель 45750dbfc6
Коммит 729950ef03
2 изменённых файлов: 96 добавлений и 6 удалений

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

@@ -487,6 +487,76 @@ func TestPreparePostForClient(t *testing.T) {
})
})
t.Run("opengraph unsafe links", func(t *testing.T) {
th := setup(t)
defer th.TearDown()
noAccessServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Fail(t, "acessed server")
}))
for _, tc := range []struct {
name string
link string
notImplmented bool
}{
{
name: "normal link",
link: "%s",
},
{
name: "normal image",
link: "%s/test-image1.png",
},
{
name: "markdown",
link: "[markdown](%s) link",
// This is because markdown links are not currently supported in the opengraph fetching code
// if you just implmented this, remove the `notImplmented` field
notImplmented: true,
},
{
name: "markdown image",
link: "![markdown](%s/test-image1.png) link",
},
} {
t.Run(tc.name, func(t *testing.T) {
t.Run("prop set", func(t *testing.T) {
prepost := &model.Post{
UserId: th.BasicUser.Id,
ChannelId: th.BasicChannel.Id,
Message: `Bla bla bla: ` + fmt.Sprintf(tc.link, noAccessServer.URL),
}
prepost.AddProp(UnsafeLinksPostProp, "true")
post, err := th.App.CreatePost(th.Context, prepost, th.BasicChannel, false, true)
require.Nil(t, err)
clientPost := th.App.PreparePostForClient(th.Context, post, false, false, false)
assert.Len(t, clientPost.Metadata.Embeds, 0)
assert.Len(t, clientPost.Metadata.Images, 0)
})
if !tc.notImplmented {
t.Run("prop not set", func(t *testing.T) {
prepost := &model.Post{
UserId: th.BasicUser.Id,
ChannelId: th.BasicChannel.Id,
Message: `Bla bla bla: ` + fmt.Sprintf(tc.link, server.URL),
}
post, err := th.App.CreatePost(th.Context, prepost, th.BasicChannel, false, true)
require.Nil(t, err)
clientPost := th.App.PreparePostForClient(th.Context, post, false, false, false)
assert.Greater(t, len(clientPost.Metadata.Embeds)+len(clientPost.Metadata.Images), 0)
})
}
})
}
})
t.Run("message attachment embed", func(t *testing.T) {
th := setup(t)
defer th.TearDown()
@@ -1319,7 +1389,7 @@ func TestGetImagesForPost(t *testing.T) {
defer th.TearDown()
ogURL := "https://example.com/index.html"
imageURL := th.App.GetSiteURL() + "/pl/qwertyuiopasdfghjklzxcvbnm"
imageURL := th.App.GetSiteURL() + "/team/pl/qwertyuiopasdfghjklzxcvbnm"
post := &model.Post{
Id: "qwertyuiopasdfghjklzxcvbnm",
@@ -2504,7 +2574,7 @@ func TestGetLinkMetadata(t *testing.T) {
*cfg.ServiceSettings.SiteURL = server.URL
})
requestURL := server.URL + "/pl/5rpoy4o3nbgwjm7gs4cm71h6ho"
requestURL := server.URL + "/team/pl/5rpoy4o3nbgwjm7gs4cm71h6ho"
timestamp := int64(1547510400000)
_, _, _, err := th.App.getLinkMetadata(th.Context, requestURL, timestamp, true, "")
@@ -2706,6 +2776,7 @@ func TestLooksLikeAPermalink(t *testing.T) {
expect bool
}{
"happy path": {input: fmt.Sprintf("%s/private-core/pl/dppezk51jp8afbhwxf1jpag66r", siteURLWithSubpath), siteURL: siteURLWithSubpath, expect: true},
"happy path redirect": {input: fmt.Sprintf("%s/_redirect/pl/dppezk51jp8afbhwxf1jpag66r", siteURLWithSubpath), siteURL: siteURLWithSubpath, expect: true},
"looks nothing like a permalink": {input: "foobar", siteURL: siteURLWithSubpath, expect: false},
"link has no subpath": {input: fmt.Sprintf("%s/private-core/pl/dppezk51jp8afbhwxf1jpag66r", "http://localhost:8065"), siteURL: siteURLWithSubpath, expect: false},
"without port": {input: fmt.Sprintf("%s/private-core/pl/dppezk51jp8afbhwxf1jpag66r", "http://localhost/foo"), siteURL: siteURLWithSubpath, expect: false},
@@ -2732,6 +2803,10 @@ func TestContainsPermalink(t *testing.T) {
const siteURLWithSubpath = "http://localhost:8065/foo"
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.SiteURL = siteURLWithSubpath
})
testCases := []struct {
Description string
Post *model.Post