Moderate severityNVD Advisory· Published Nov 6, 2023· Updated Sep 17, 2024
Denial of Service via Link Preview in /api/v4/redirect_location
CVE-2023-5969
Description
Mattermost fails to properly sanitize the request to /api/v4/redirect_location allowing an attacker, sending a specially crafted request to /api/v4/redirect_location, to fill up the memory due to caching large items.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/mattermost/mattermost-server/v6Go | < 7.8.12 | 7.8.12 |
github.com/mattermost/mattermost/server/v8Go | >= 8.0.0, < 8.0.4 | 8.0.4 |
github.com/mattermost/mattermost/server/v8Go | >= 8.1.0, < 8.1.3 | 8.1.3 |
github.com/mattermost/mattermost/server/v8Go | >= 9.0.0, < 9.0.1 | 9.0.1 |
Affected products
1- Range: 0
Patches
177f094c7ee8cMM-54219 - Fix: Improve limits on redirectLocationDataCache (#24429) (#24568)
2 files changed · +44 −5
server/channels/api4/system.go+17 −5 modified@@ -26,9 +26,11 @@ import ( ) const ( - RedirectLocationCacheSize = 10000 - DefaultServerBusySeconds = 3600 - MaxServerBusySeconds = 86400 + RedirectLocationCacheSize = 10000 + RedirectLocationMaximumLength = 2100 + RedirectLocationCacheExpiry = 1 * time.Hour + DefaultServerBusySeconds = 3600 + MaxServerBusySeconds = 86400 ) var redirectLocationDataCache = cache.NewLRU(cache.LRUOptions{ @@ -589,7 +591,7 @@ func getRedirectLocation(c *Context, w http.ResponseWriter, r *http.Request) { res, err := client.Head(url) if err != nil { // Cache failures to prevent retries. - redirectLocationDataCache.SetWithExpiry(url, "", 1*time.Hour) + redirectLocationDataCache.SetWithExpiry(url, "", RedirectLocationCacheExpiry) // Always return a success status and a JSON string to limit information returned to client. w.Write([]byte(model.MapToJSON(m))) return @@ -600,7 +602,17 @@ func getRedirectLocation(c *Context, w http.ResponseWriter, r *http.Request) { }() location = res.Header.Get("Location") - redirectLocationDataCache.SetWithExpiry(url, location, 1*time.Hour) + + // If the location length is > 2100, we can probably ignore. Fixes https://mattermost.atlassian.net/browse/MM-54219 + if len(location) > RedirectLocationMaximumLength { + // Treating as a "failure". Cache failures to prevent retries. + redirectLocationDataCache.SetWithExpiry(url, "", RedirectLocationCacheExpiry) + // Always return a success status and a JSON string to limit information returned to client. + w.Write([]byte(model.MapToJSON(m))) + return + } + + redirectLocationDataCache.SetWithExpiry(url, location, RedirectLocationCacheExpiry) m["location"] = location w.Write([]byte(model.MapToJSON(m)))
server/channels/api4/system_test.go+27 −0 modified@@ -673,6 +673,33 @@ func TestRedirectLocation(t *testing.T) { _, resp, err = client.GetRedirectLocation(context.Background(), "", "") require.Error(t, err) CheckUnauthorizedStatus(t, resp) + + // Check that too-long redirect locations are ignored + *th.App.Config().ServiceSettings.EnableLinkPreviews = true + urlPrefix := "https://example.co" + almostTooLongUrl := urlPrefix + strings.Repeat("a", 2100-len(urlPrefix)) + testServer2 := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + res.Header().Set("Location", almostTooLongUrl) + res.WriteHeader(http.StatusFound) + res.Write([]byte("body")) + })) + defer func() { testServer2.Close() }() + + actual, _, err = th.SystemAdminClient.GetRedirectLocation(context.Background(), testServer2.URL, "") + require.NoError(t, err) + assert.Equal(t, almostTooLongUrl, actual) + + tooLongUrl := urlPrefix + strings.Repeat("a", 2101-len(urlPrefix)) + testServer3 := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + res.Header().Set("Location", tooLongUrl) + res.WriteHeader(http.StatusFound) + res.Write([]byte("body")) + })) + defer func() { testServer3.Close() }() + + actual, _, err = th.SystemAdminClient.GetRedirectLocation(context.Background(), testServer3.URL, "") + require.NoError(t, err) + assert.Equal(t, "", actual) } func TestSetServerBusy(t *testing.T) {
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5News mentions
0No linked articles in our index yet.