CVE-2026-35407 Overview
CVE-2026-35407 is an authorization bypass vulnerability in Saleor, an open-source e-commerce platform. The flaw exists in the account email change workflow where the confirmation flow fails to verify that the email change confirmation token was issued for the authenticated user. This business logic error allows an attacker to replay a valid email-change token generated for one account while authenticated as a different account, resulting in unauthorized email address changes.
Critical Impact
An attacker with a valid email-change token can hijack other users' email addresses by replaying the token while authenticated as a different account, potentially enabling account takeover scenarios.
Affected Products
- Saleor versions 2.10.0 through 3.20.117
- Saleor versions 3.21.0 through 3.21.53
- Saleor versions 3.22.0 through 3.22.46
- Saleor versions 3.23.0a0 through 3.23.0a2
Discovery Timeline
- 2026-04-08 - CVE-2026-35407 published to NVD
- 2026-04-08 - Last updated in NVD database
Technical Details for CVE-2026-35407
Vulnerability Analysis
This vulnerability stems from an improper authorization check (CWE-285) in Saleor's email change confirmation workflow. When a user initiates an email change request, the system generates a JWT token containing the new email address. During the confirmation step, the application validates that the token is structurally valid and not expired, but critically fails to verify that the token was actually issued for the currently authenticated user.
This missing user-token binding creates a token replay vulnerability where any valid email-change token can be used by any authenticated user. The impact allows attackers to change other accounts' email addresses to an email they control, which could lead to complete account takeover through password reset flows.
Root Cause
The root cause is a missing authorization check in the confirm_email_change mutation. The confirmation endpoint validates the JWT token's signature and expiration but does not compare the token's subject (the user who requested the email change) against the currently authenticated user making the confirmation request. This violates the principle that security tokens should be bound to specific users and sessions.
Attack Vector
The attack requires network access and involves multiple steps with user interaction. An attacker must first obtain a valid email-change token (either by generating one for their own account or intercepting one intended for another user). The attacker then authenticates as a different target account and submits the stolen token to the confirmation endpoint. Because the system doesn't verify user-token binding, the target account's email is changed to the email specified in the token.
# Security patch adding JWT token type constant
# Source: https://github.com/saleor/saleor/commit/7be352fa8c35875d6e66d36493ca7c14c101bd64
JWT_ACCESS_TYPE = "access"
JWT_REFRESH_TYPE = "refresh"
+JWT_CONFIRM_CHANGE_EMAIL_TYPE = "confirm-email-change"
JWT_THIRDPARTY_ACCESS_TYPE = "thirdparty"
JWT_REFRESH_TOKEN_COOKIE_NAME = "refreshToken"
The patch introduces a dedicated JWT token type for email change confirmation, enabling proper token validation and user binding in the confirmation flow.
Detection Methods for CVE-2026-35407
Indicators of Compromise
- Unusual email change confirmation requests where the token's original user differs from the authenticated user
- Multiple email change confirmations originating from the same IP address for different user accounts
- Rapid succession of email change requests followed by password reset attempts
- Authentication logs showing email changes for accounts without corresponding email change initiation requests
Detection Strategies
- Implement logging that captures both the token subject and the authenticated user during email change confirmations
- Monitor for anomalies where email change tokens are used by users who did not generate them
- Alert on patterns where a single session or IP address confirms email changes for multiple accounts
- Review GraphQL mutation logs for confirmEmailChange operations with mismatched user contexts
Monitoring Recommendations
- Enable detailed audit logging for all account modification operations in Saleor
- Set up alerts for email change confirmations that occur without a corresponding email change request from the same user
- Monitor for increased password reset requests immediately following email changes
- Implement rate limiting on email change confirmation endpoints to slow automated exploitation
How to Mitigate CVE-2026-35407
Immediate Actions Required
- Upgrade Saleor to version 3.20.118, 3.21.54, 3.22.47, or 3.23.0a3 or later immediately
- Audit recent email change operations for signs of unauthorized modifications
- Review accounts where email addresses were changed and verify with users through alternative contact methods
- Consider temporarily disabling the email change functionality if immediate patching is not possible
Patch Information
Saleor has released security patches across multiple supported branches. Organizations should update to the following fixed versions:
- Version 3.20.118 for the 3.20.x branch
- Version 3.21.54 for the 3.21.x branch
- Version 3.22.47 for the 3.22.x branch
- Version 3.23.0a3 for the 3.23.x alpha branch
The patches add proper user-token binding verification to the email change confirmation flow. For detailed technical information, refer to the GitHub Security Advisory and associated commit fixes.
Workarounds
- Disable the email change functionality entirely by removing or restricting access to the requestEmailChange and confirmEmailChange GraphQL mutations
- Implement a custom middleware that validates user-token binding before processing email change confirmations
- Add manual approval workflows for email change requests requiring administrator verification
- Use network-level controls to restrict access to account management endpoints to trusted networks
# Example: Disable email change mutations via Saleor plugin or middleware
# Add to your custom Saleor plugin to block vulnerable endpoints until patched
# In settings.py or plugin configuration:
# DISABLED_MUTATIONS = ["requestEmailChange", "confirmEmailChange"]
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

