mirror of
https://github.com/mattermost/mattermost.git
synced 2026-04-15 05:57:37 -04:00
* MM-66813 - Add server origin verification to mobile SSO callbacks * Enhance mobile SSO security and deprecate code-exchange * Update code-exchange deprecation to follow MM standards * Use config SiteURL for srv param, fix flow terminology --------- Co-authored-by: Mattermost Build <build@mattermost.com>
88 lines
3 KiB
Go
88 lines
3 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package web
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
)
|
|
|
|
// TestSamlCallbackIncludesSrvParameter verifies that mobile SAML callbacks
|
|
// include the 'srv' parameter for origin verification
|
|
func TestSamlCallbackIncludesSrvParameter(t *testing.T) {
|
|
// The 'srv' parameter is added to mobile callbacks to allow the client
|
|
// to verify the server origin
|
|
|
|
t.Run("srv parameter should be included in redirect URL construction", func(t *testing.T) {
|
|
// Verify the pattern: when we construct a redirect URL for mobile,
|
|
// it should include "srv" parameter with the server's site URL
|
|
|
|
siteURL := "https://mattermost.example.com"
|
|
sessionToken := "test-session-token"
|
|
csrfToken := "test-csrf-token"
|
|
|
|
// Simulate what the code does when constructing the callback
|
|
params := map[string]string{
|
|
model.SessionCookieToken: sessionToken,
|
|
model.SessionCookieCsrf: csrfToken,
|
|
"srv": siteURL,
|
|
}
|
|
|
|
// Verify all expected parameters are present
|
|
assert.Equal(t, sessionToken, params[model.SessionCookieToken])
|
|
assert.Equal(t, csrfToken, params[model.SessionCookieCsrf])
|
|
assert.Equal(t, siteURL, params["srv"])
|
|
})
|
|
|
|
t.Run("srv parameter detects server mismatch", func(t *testing.T) {
|
|
// Scenario: The srv parameter from callback doesn't match expected server
|
|
// Mobile should detect the mismatch
|
|
|
|
expectedServer := "https://server-a.example.com"
|
|
actualSrvFromCallback := "https://server-b.example.com"
|
|
|
|
// This is the check that should happen in mobile
|
|
isMismatch := expectedServer != actualSrvFromCallback
|
|
assert.True(t, isMismatch, "Should detect server mismatch")
|
|
})
|
|
|
|
t.Run("srv parameter allows legitimate login", func(t *testing.T) {
|
|
// Scenario: Normal login to legitimate server
|
|
// Server adds srv=server.com to callback
|
|
// Mobile verifies: expected == srv
|
|
|
|
expectedServer := "https://server.example.com"
|
|
actualSrvFromCallback := "https://server.example.com"
|
|
|
|
// This is the check that should happen in mobile
|
|
isLegitimate := expectedServer == actualSrvFromCallback
|
|
assert.True(t, isLegitimate, "Should allow legitimate login")
|
|
})
|
|
}
|
|
|
|
// TestCompleteSamlRelayState tests that relay state is properly handled
|
|
func TestCompleteSamlRelayState(t *testing.T) {
|
|
t.Run("should decode relay state correctly", func(t *testing.T) {
|
|
relayProps := map[string]string{
|
|
"action": model.OAuthActionMobile,
|
|
"redirect_to": "mmauth://callback",
|
|
}
|
|
|
|
relayState := base64.StdEncoding.EncodeToString([]byte(model.MapToJSON(relayProps)))
|
|
|
|
// Decode and verify
|
|
decoded, err := base64.StdEncoding.DecodeString(relayState)
|
|
require.NoError(t, err)
|
|
|
|
decodedProps := model.MapFromJSON(strings.NewReader(string(decoded)))
|
|
assert.Equal(t, model.OAuthActionMobile, decodedProps["action"])
|
|
assert.Equal(t, "mmauth://callback", decodedProps["redirect_to"])
|
|
})
|
|
}
|