Oct 7, 2026·6 min read·2 visits
Payload CMS fails to properly validate the redirect parameter on login and registration pages, enabling attackers to execute open redirects by injecting control characters into the path.
An open redirect vulnerability exists in Payload CMS within its Next.js-based authentication routing components. The sanitization utility fails to properly account for control characters and ambiguous encodings, allowing unauthenticated attackers to redirect users to external malicious domains after successful authentication.
Payload CMS implements administrative portals and custom application authentication routing utilizing Next.js components. When users interface with the LoginForm and CreateAccountForm elements, a redirect query parameter determines the post-authentication destination. This mechanism aims to maintain state and context across sessions by returning users to their requested page.
The initial design of this routing interface exposed a structural attack surface. The validation algorithm assumed that any path starting with a single forward slash represented a local relative resource, while paths starting with a double forward slash represented external resources. Attackers exploit this assumption by inserting non-standard characters into the redirect string.
This vulnerability is classified under CWE-601 (URL Redirection to Untrusted Site). It presents an initial access risk because it permits attackers to generate trustworthy-looking links pointing to legitimate domains that ultimately redirect users to attacker-controlled pages after authentication. Secure deployments require absolute enforcement of strict URL structure verification.
The root cause of this vulnerability lies in the input validation logic within the getSafeRedirect utility located in packages/payload/src/utilities/getSafeRedirect.ts. Prior to version 3.88.0, the validation relied on simple pattern matching. It verified that the redirection target started with a single forward slash and did not start with dual forward slashes to prevent protocol-relative redirection.
This validation design fails to account for how modern web browsers parse and normalize navigation URLs. Characters such as Tab (%09), Carriage Return (%0D), and Line Feed (%0A) are processed inconsistently across browser platforms. Google Chrome and Apple Safari strip out or ignore tab characters and newlines inside paths during navigation operations to normalize malformed links.
Consequently, an input path containing a control character, such as /%09/attacker.com, passes the legacy validation test because it starts with a single slash followed by a control character. However, once the browser processes the normalized URL string, the tab character is discarded. The resulting string resolves to //attacker.com, which is interpreted as a protocol-relative absolute URL pointing directly to the external domain.
An analysis of the patch commit reveals the implementation of multi-layered defensive validation within the getSafeRedirect helper. The update introduces three explicit checks to eliminate parser differentials. The system now searches for raw control characters, rejects ambiguous percent-encoded path prefixes, and validates the resolution using the native WHATWG URL API.
// The patched validation implementation
export const getSafeRedirect = ({
allowAbsoluteUrls,
fallbackTo,
redirectTo,
}: {
allowAbsoluteUrls?: boolean
fallbackTo: string
redirectTo: string
}): string => {
if (!redirectTo) {
return fallbackTo
}
const redirectPath = redirectTo.trim()
// 1. Detect control characters (ASCII <= 31 or 127)
const hasControlCharacters = [...redirectPath].some((character) => {
const code = character.charCodeAt(0)
return code <= 31 || code === 127
})
// 2. Reject ambiguous percent-encoded path prefixes
const hasAmbiguousPathPrefix = /^\/%(?:25)*(?:09|0a|0d|2f|5c)/i.test(redirectPath)
// 3. Resolve origin against a dummy localhost base using the WHATWG URL API
let parsedRedirect: URL
try {
parsedRedirect = new URL(redirectPath, 'http://localhost')
} catch {
return fallbackTo
}
const isSafeRedirect =
!hasControlCharacters &&
!hasAmbiguousPathPrefix &&
redirectPath.startsWith('/') &&
parsedRedirect.origin === 'http://localhost' &&
!redirectPath.startsWith('//')
return isSafeRedirect ? redirectPath : fallbackTo
}The introduction of the WHATWG URL constructor forces the input string to be evaluated using the same standardization rules that browsers use. If the normalized path resolves to an origin other than the localized base, the utility automatically drops the parameter and selects the fallback destination. This approach closes the gap between backend server-side validation and browser-side interpretation.
Exploitation of CVE-2026-105846 relies on social engineering and link distribution. The attacker targets instances running versions within the vulnerable range. The attack does not require any prior privileges or active sessions on the target application.
The attacker crafts a URL targeting the authentication endpoint of the victim site. They append a redirect parameter containing the bypass, such as https://example.com/login?redirect=/%09/malicious-domain.com. The victim navigates to this URL, verifies that the primary domain is legitimate, and enters their credentials. After processing the successful login, the application evaluates the bypass string, accepts it, and returns the location header to the browser, which redirects the user's viewport to the external site.
The impact of this vulnerability is assessed at Medium severity, with a CVSS base score of 6.1. The attack vector is Network, requiring Low complexity and requiring User Interaction. Scope is Changed because the browser transitions from the original origin to an external security domain.
Although an open redirect vulnerability does not allow an attacker to execute arbitrary system code or directly modify backend storage, it serves as a critical facilitator for phishing campaigns. Attackers can clone the Payload CMS administrative dashboard on the target destination. When victims are redirected immediately post-login, they assume their session expired or failed and re-enter their credentials, leaking passwords and session tokens directly to the attacker.
In environments where multi-factor authentication or single sign-on is implemented, this flaw can bypass certain security boundaries. The user completes primary authentication on the real site, and the subsequent redirection steals the active session state or authentication cookies from subsequent client headers.
Remediation requires upgrading the underlying payload and @payloadcms/next dependencies. For stable deployments, administrators must transition to version 3.88.0 or higher. For canary-track deployments, the vulnerability is fully addressed in version 4.0.0-canary.27 or higher.
If immediate dependency updates are not feasible, network administrators should deploy Web Application Firewall rules to block requests containing control characters within the redirect parameter. WAF engines should search for URL-encoded representations of tabs, line feeds, and backslashes occurring after a forward slash.
Furthermore, developers should review custom routing implementations. Any component handling URL redirections must utilize native URL parsers rather than relying on regex or prefix testing alone to ensure matching behaviors between server and client parsing engines.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
payload payloadcms | >= 3.40.0, < 3.88.0 | 3.88.0 |
payload payloadcms | >= 4.0.0-canary.0, < 4.0.0-canary.27 | 4.0.0-canary.27 |
@payloadcms/next payloadcms | >= 3.31.0, < 3.88.0 | 3.88.0 |
@payloadcms/next payloadcms | >= 4.0.0-canary.0, < 4.0.0-canary.27 | 4.0.0-canary.27 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-601 |
| Attack Vector | Network (AV:N) |
| CVSS Score | 6.1 (Medium) |
| EPSS Score | Not available |
| Exploit Status | Proof-of-Concept |
| KEV Status | Not Listed |
The application accepts an untrusted input URL parameter and redirects the user to that URL without validating the destination host fully, permitting redirection to malicious external sites.
A critical SQL Injection and access control bypass vulnerability was identified in Payload CMS database adapters (SQLite and PostgreSQL using Drizzle ORM internally). The vulnerability arises from case-sensitive logical operator checks during path validation and unvalidated sort queries. This allows remote attackers to bypass access control rules, execute unauthorized queries, and retrieve sensitive data through blind SQL injection side channels.
A critical prototype pollution vulnerability in the import-export plugin of Payload CMS allows unauthenticated remote attackers to bypass access controls and achieve remote code execution.
CVE-2026-105806 is an improper access control vulnerability within the Model Context Protocol (MCP) plugin for Payload CMS. Authenticated users with low privileges can manipulate API key creation and mapping to associate keys with arbitrary users, including administrators. This allows total session takeovers and privilege escalation via MCP-authenticated API requests.
An access control vulnerability in `@payloadcms/plugin-stripe` allows authenticated low-privilege users to bypass authorization boundaries and execute arbitrary, highly privileged operations on the connected Stripe platform via an exposed REST proxy.
A critical access control bypass vulnerability (CVE-2026-105851) in Payload CMS allows authenticated users to bypass field-level access controls during document duplication. By duplicating high-privilege documents, such as administrator accounts, standard users can inherit sensitive fields (e.g., role configurations or API keys), leading to privilege escalation.
CVE-2026-105853 is a high-severity information disclosure vulnerability in Payload CMS that affects authentication-enabled collections. In vulnerable versions, the application fails to properly serialize and sanitize user documents during token refresh and password reset operations. This deficiency leaks hidden and read-restricted fields to unauthorized actors. Additionally, a logical flaw in token refresh validation allows low-privileged users to cross collection boundaries, exposing sensitive configuration details and administrative metadata.