VYPR
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.

PackageAffected versionsPatched versions
github.com/mattermost/mattermost-server/v6Go
< 7.8.127.8.12
github.com/mattermost/mattermost/server/v8Go
>= 8.0.0, < 8.0.48.0.4
github.com/mattermost/mattermost/server/v8Go
>= 8.1.0, < 8.1.38.1.3
github.com/mattermost/mattermost/server/v8Go
>= 9.0.0, < 9.0.19.0.1

Affected products

1

Patches

1
77f094c7ee8c

MM-54219 - Fix: Improve limits on redirectLocationDataCache (#24429) (#24568)

https://github.com/mattermost/mattermostMattermost BuildSep 15, 2023via ghsa
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

5

News mentions

0

No linked articles in our index yet.