VYPR
Low severityNVD Advisory· Published Sep 15, 2025· Updated Sep 15, 2025

Open redirect in OAuth login

CVE-2025-9084

Description

Mattermost versions 10.5.x <= 10.5.9 fail to properly validate redirect URLs which allows attackers to redirect users to malicious sites via crafted OAuth login URLs

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/mattermost/mattermost/server/v8Go
< 8.0.0-202508080704-39bd251fe4f6008.0.0-202508080704-39bd251fe4f600
github.com/mattermost/mattermost-serverGo
>= 10.5.0, < 10.5.1010.5.10

Affected products

1

Patches

1
39bd251fe4f6

[MM-65015] Restore Mobile redirection on oauth login (#33626) (#33637)

https://github.com/mattermost/mattermostMattermost BuildAug 8, 2025via ghsa
3 files changed · +21 6
  • server/channels/web/oauth.go+16 4 modified
    @@ -11,6 +11,7 @@ import (
     	"net/url"
     	"path"
     	"path/filepath"
    +	"slices"
     	"strings"
     	"time"
     
    @@ -23,6 +24,10 @@ import (
     	"github.com/mattermost/mattermost/server/v8/channels/utils/fileutils"
     )
     
    +const (
    +	callbackHost = "callback"
    +)
    +
     func (w *Web) InitOAuth() {
     	// API version independent OAuth 2.0 as a service provider endpoints
     	w.MainRouter.Handle("/oauth/authorize", w.APIHandlerTrustRequester(authorizeOAuthPage)).Methods(http.MethodGet)
    @@ -316,7 +321,7 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
     			hasRedirectURL = redirectURL != ""
     		}
     	}
    -	redirectURL = fullyQualifiedRedirectURL(c.GetSiteURLHeader(), redirectURL)
    +	redirectURL = fullyQualifiedRedirectURL(c.GetSiteURLHeader(), redirectURL, c.App.Config().NativeAppSettings.AppCustomURLSchemes)
     
     	renderError := func(err *model.AppError) {
     		if isMobile && hasRedirectURL {
    @@ -536,7 +541,7 @@ func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
     	http.Redirect(w, r, authURL, http.StatusFound)
     }
     
    -func fullyQualifiedRedirectURL(siteURLPrefix, targetURL string) string {
    +func fullyQualifiedRedirectURL(siteURLPrefix, targetURL string, otherValidSchemes []string) string {
     	parsed, err := url.Parse(targetURL)
     	if err != nil {
     		return siteURLPrefix
    @@ -545,8 +550,15 @@ func fullyQualifiedRedirectURL(siteURLPrefix, targetURL string) string {
     	if err != nil {
     		return siteURLPrefix
     	}
    -
    -	// Check if the targetURL is a valid URL and is within the siteURLPrefix
    +	// mobile access
    +	if slices.Contains(otherValidSchemes, fmt.Sprintf("%v://", parsed.Scheme)) &&
    +		parsed.Host == callbackHost &&
    +		parsed.Path == "" &&
    +		parsed.RawQuery == "" &&
    +		parsed.Fragment == "" {
    +		return targetURL
    +	}
    +	// Check if the targetURL is valid and within the siteURLPrefix, excluding native app schemes like mmauth://
     	sameScheme := parsed.Scheme == prefixParsed.Scheme
     	sameHost := parsed.Host == prefixParsed.Host
     	safePath := strings.HasPrefix(path.Clean(parsed.Path), path.Clean(prefixParsed.Path))
    
  • server/channels/web/oauth_test.go+4 1 modified
    @@ -849,6 +849,7 @@ func (th *TestHelper) AddPermissionToRole(permission string, roleName string) {
     
     func TestFullyQualifiedRedirectURL(t *testing.T) {
     	const siteURL = "https://xxx.yyy/mm"
    +
     	for target, expected := range map[string]string{
     		"":                                     siteURL,
     		"/":                                    siteURL + "/",
    @@ -869,9 +870,11 @@ func TestFullyQualifiedRedirectURL(t *testing.T) {
     		"https://xxx.yyy/mm/some-path#section": siteURL + "/some-path#section",
     		"https://xxx.yyy/mm/../malicious-path": siteURL,
     		":foo":                                 siteURL,
    +		"mmauth://callback":                    "mmauth://callback",
    +		"mmauth://xxx.yyy/mm":                  siteURL, // invalid mobile URL (wrong host)
     	} {
     		t.Run(target, func(t *testing.T) {
    -			require.Equal(t, expected, fullyQualifiedRedirectURL(siteURL, target))
    +			require.Equal(t, expected, fullyQualifiedRedirectURL(siteURL, target, []string{"mmauth://"}))
     		})
     	}
     }
    
  • server/channels/web/saml.go+1 1 modified
    @@ -117,7 +117,7 @@ func completeSaml(c *Context, w http.ResponseWriter, r *http.Request) {
     		redirectURL = val
     		hasRedirectURL = val != ""
     	}
    -	redirectURL = fullyQualifiedRedirectURL(c.GetSiteURLHeader(), redirectURL)
    +	redirectURL = fullyQualifiedRedirectURL(c.GetSiteURLHeader(), redirectURL, c.App.Config().NativeAppSettings.AppCustomURLSchemes)
     
     	handleError := func(err *model.AppError) {
     		if isMobile && hasRedirectURL {
    

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

4

News mentions

0

No linked articles in our index yet.