MM-66372: Improve OAuth state token validation (#34296) (#34300)

Этот коммит содержится в:
Mattermost Build
2025-10-28 02:46:33 +02:00
коммит произвёл GitHub
родитель f361e7d75a
Коммит 46b5c436bb
2 изменённых файлов: 210 добавлений и 4 удалений

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

@@ -850,10 +850,13 @@ func (a *App) AuthorizeOAuthUser(c request.CTX, w http.ResponseWriter, r *http.R
return nil, stateProps, nil, model.NewAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.invalid_state.app_error", nil, "", http.StatusBadRequest).Wrap(cookieErr)
}
expectedTokenExtra := generateOAuthStateTokenExtra(stateEmail, stateAction, cookie.Value)
if expectedTokenExtra != expectedToken.Extra {
err := errors.New("Extra token value does not match token generated from state")
return nil, stateProps, nil, model.NewAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.invalid_state.app_error", nil, "", http.StatusBadRequest).Wrap(err)
tokenEmail, tokenAction, tokenCookie, parseErr := parseOAuthStateTokenExtra(expectedToken.Extra)
if parseErr != nil {
return nil, stateProps, nil, model.NewAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.invalid_state.app_error", nil, "", http.StatusBadRequest).Wrap(parseErr)
}
if tokenEmail != stateEmail || tokenAction != stateAction || tokenCookie != cookie.Value {
return nil, stateProps, nil, model.NewAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.invalid_state.app_error", nil, "", http.StatusBadRequest).Wrap(errors.New("invalid state token"))
}
appErr = a.DeleteToken(expectedToken)
@@ -1037,3 +1040,18 @@ func (a *App) SwitchOAuthToEmail(c request.CTX, email, password, requesterId str
func generateOAuthStateTokenExtra(email, action, cookie string) string {
return email + ":" + action + ":" + cookie
}
// parseOAuthStateTokenExtra parses a token extra string in the format "email:action:cookie".
// Returns an error if the token does not contain exactly 3 colon-separated parts.
func parseOAuthStateTokenExtra(tokenExtra string) (email, action, cookie string, err error) {
parts := strings.Split(tokenExtra, ":")
if len(parts) != 3 {
return "", "", "", fmt.Errorf("invalid token format: expected exactly 3 parts separated by ':', got %d", len(parts))
}
email = parts[0]
action = parts[1]
cookie = parts[2]
return email, action, cookie, nil
}