Open Redirect Vulnerability: Attack Scenarios Explained
Table of Contents

An open redirect is a CWE-601 flaw where an application accepts an attacker-controlled URL and forwards users without validation, turning a trusted link into a trust-abuse vector. A vulnerability database indexed 2,526 vulnerabilities referencing CWE-601, showing that this is a widespread design pattern rather than an isolated framework bug.
That prevalence is counterintuitive because open redirects often look harmless during triage. The server may execute no injected code, expose no database query, and return an ordinary HTTP response. Yet the application can still lend its trusted domain to a phishing campaign, leak authentication material, or carry privileged headers across an untrusted boundary.
The risk depends on where the redirect sits. A marketing link tracker has a different threat profile from a password recovery endpoint, OAuth callback, logout handler, or internal service request. Treating them all as navigation conveniences is how a low-severity finding becomes an authentication problem.
What Is an Open Redirect Vulnerability
An open redirect vulnerability occurs when an application takes attacker-controlled input and uses it as the destination of a redirect without checking whether that destination is permitted. The input might arrive through a query parameter such as next or returnUrl, a form field, an HTTP header, a database record, or an OAuth callback value. The application then places it in an HTTP Location header or passes it to a browser navigation sink such as window.location.
The weakness is formally classified as CWE-601, URL Redirection to Untrusted Site. Its practical danger comes from trust transfer. A victim first sees a genuine application URL, perhaps in an email or message. The trusted URL then forwards the browser to an attacker-controlled domain, where a counterfeit login page can collect credentials or deliver malicious content.

The redirect doesn't need to compromise the server to create harm. The attacker only needs a crafted link and a convincing reason for the victim to follow it. That makes this flaw different from code execution, but not necessarily less relevant to identity security. A redirect after login, password reset, or account enrollment can be part of the same chain as credential theft or session compromise.
Why the trusted origin matters
A link beginning with a familiar organization's domain can reduce suspicion. Security controls that inspect links may also evaluate the initial domain differently from the final destination, especially when the redirect is nested, encoded, or chained through several services. The attacker gets a credibility benefit without owning the legitimate application.
This is why application security teams should include redirect behavior in their broader application security vulnerability review process. The relevant question isn't only whether an endpoint redirects. It's whether untrusted data can influence a security-sensitive navigation decision.
Practical rule: A redirect endpoint is a security boundary whenever it follows authentication, handles identity state, or can transport security credentials.
The design failure is usually simple: accept a complete URL, pass it to a redirect function, and assume the browser will behave benignly. Browsers parse URLs according to rules that include schemes, userinfo, ports, encoded delimiters, fragments, and backslashes. A validation method that treats a URL as an ordinary string can approve a value the browser interprets very differently.
Why Open Redirects Escalate Beyond Phishing
The familiar attack starts with a trusted link and ends at a fake login page. For example, an attacker might place an untrusted destination in a login flow's next parameter. The victim sees the legitimate domain, completes the expected sign-in interaction, and then arrives at a page controlled by the attacker. The redirect hasn't stolen the credentials by itself, but it has made the delivery mechanism more believable.
That model is incomplete for systems that send requests on behalf of an authenticated user. In those flows, the redirect may influence where a browser or server sends authorization material. The result can move from deceptive navigation to token exposure and privilege abuse.
The GitHub Enterprise Server example
CVE-2026-0573 demonstrates the distinction. The issue affected GitHub Enterprise Server versions before 3.19.2, 3.18.4, 3.17.10, 3.16.13, 3.15.17, and 3.14.22. The NVD assigned it a CVSS v4 base score of 7.6, rated High.
An authenticated user who could induce a legacy redirect could cause an attacker-controlled HTTP redirect to preserve an authorization header containing a privileged JWT. The affected flow could expose an Actions.ManageOrgs token and create a path toward remote code execution. Exploitation required access to the affected GitHub Enterprise Server instance and an authenticated user, but those prerequisites don't make the design issue ordinary phishing.
The important observation is architectural. A redirect that preserves an authorization header is no longer just telling a browser where to go. It's participating in a server-to-server or privileged request flow, and the destination becomes part of the authorization decision.
Authentication changes the severity model
A related example is CVE-2022-23527, an open redirect in Apache's mod_auth_openidc. Its relevance is not that every open redirect behaves the same way. It shows why teams must inspect the identity protocol around the redirect rather than assigning severity from the endpoint name alone.
A redirect is low risk only when the surrounding flow is low risk. Once credentials, bearer tokens, OAuth state, or privileged headers can cross the boundary, the threat model changes.
Reviewers should trace what happens before and after the redirect:
- Before navigation: Does the flow authenticate the user, set a session, or issue an authorization code?
- At navigation: Does the application preserve cookies, bearer tokens, authorization headers, or state values?
- After navigation: Can the destination receive a code, token, referrer, or account-management action?
This analysis also explains why a scanner finding can be misleading. The same CWE label may describe a promotional redirect in one service and a credential-bearing identity transition in another. The control remains destination validation, but the business impact depends on the security material attached to the flow.
Redirect Types and Their Hidden Dangers
The source of the destination determines where defenders need to look. A server-side endpoint that reflects a query parameter is visible in request logs, while a browser-side router can redirect without any corresponding server Location header. Stored destinations create another problem, because the malicious value may be inserted long before a victim triggers it.
The three useful categories are reflected, stored, and DOM-based redirects. They describe data flow, not severity. Any of them can become dangerous when connected to authentication, authorization, or sensitive user journeys.

Reflected redirects
A reflected redirect takes the destination from the current request and returns it immediately. Common sources include query parameters, submitted form fields, URL fragments processed by client code, and values derived from the Referer header.
These are often the easiest to find. Search server routes for redirect APIs, inspect Location responses, and follow every user-controlled value into the redirect call. Testing should include the login, logout, password recovery, invitation, and error-handling routes, not just endpoints named /redirect.
Stored redirects
A stored redirect retrieves its destination from persistent application data. An administrator might save a callback URL, a user profile might contain a return location, or an integration record might hold a destination that later reaches a redirect response.
The delayed trigger changes the investigation. A clean request log doesn't prove the flow is safe because the malicious value may have entered through an earlier administrative action, import, API request, or configuration update. Security review needs to follow the value from storage and validation through every later read.
DOM-based redirects
A DOM-based redirect happens in browser-side JavaScript. Code may read a query parameter, fragment, or browser storage value and assign it to window.location, a framework router, or another navigation sink. Backend scanners can miss this because the server returns an ordinary page.
Inspect event handlers, route guards, client-side tracking helpers, and single-page application navigation tables. URL encoding and decoding helpers deserve particular scrutiny, especially when teams are already working with Java URL encoding behavior, because transformations can alter how a browser ultimately parses a value.
The testing scope should match the architecture. Server-side review follows request and storage paths. Browser-side review follows script execution and navigation sinks. Configuration review examines destinations loaded from deployment metadata or integration settings.
Secure Redirect Patterns and Validation Rules
The reliable fix is structural URL validation, not a growing collection of blocked strings. A secure implementation parses the candidate with the platform's standard URL parser, then evaluates the parsed components against an explicit policy. OWASP's guidance on unvalidated redirects recommends comparing the canonical scheme, hostname, effective port, and, where necessary, path against an allowlist.
That approach matters because a URL isn't just a string with a hostname somewhere inside it. Userinfo syntax, encoded delimiters, alternate schemes, backslashes, and parser differences can make a value look acceptable to a string check while directing the browser elsewhere.
Prefer the smallest permitted destination
For same-site navigation, accept only a relative path. A framework helper designed to reject external destinations is preferable to custom concatenation. The application should also define a safe fallback for missing, malformed, or rejected values.
For legitimate external navigation, don't accept an arbitrary complete URL when an identifier will do. Map an opaque server-side ID to an approved destination, validate that the current user is authorized to use the destination, and redirect using the parsed value that passed validation.
A practical policy looks like this:
- Relative paths: Permit local paths while rejecting protocol-relative forms and ambiguous syntax.
- Absolute URLs: Require an approved scheme, exact hostname, permitted port, and approved path where the flow needs that restriction.
- External destinations: Resolve an opaque identifier through a server-side allowlist instead of accepting a complete URL.
- Malformed input: Reject it or use a safe local destination. Don't attempt to repair it and then redirect.
- Validated output: Redirect with the already parsed and validated value, not a separately transformed version.
Why common shortcuts fail
startsWith, contains, regular-expression-only checks, and blocklists are weak controls. A check for an approved hostname at the beginning of a string can be defeated by userinfo syntax such as trusted.example@attacker.example. Encoding, mixed case, alternate ports, fragments, and backslashes can also create disagreement between the validator and the browser.
The same problem affects blocklists. An attacker doesn't need to use the exact string a developer anticipated if the parser accepts another representation of an external destination. Allowlisting what the application needs is more maintainable and produces a smaller decision surface.
Validation rule: Parse first, canonicalize through the parser, compare explicit components, and redirect only to the approved parsed result.
A warning page can display the complete destination before navigation, which may help users recognize an unexpected external site. It isn't a substitute for server-side validation. A clear warning doesn't make an attacker-controlled redirect safe, particularly when the redirect appears inside an authentication or account-management flow.
Centralize these rules in shared middleware or a shared library. If every product team writes a slightly different redirect helper, the organization will accumulate inconsistent interpretations of schemes, ports, hostnames, and relative paths. The policy should also be covered by automated tests and reviewed whenever a new callback or return URL is introduced.
Securing OAuth and Token Flows in Practice
OAuth makes redirect handling more consequential because the callback is part of an identity exchange. A user authenticates with an authorization server, the authorization server sends a code or token to a registered redirect URI, and the client completes the flow. If an attacker can substitute an untrusted destination into that sequence, the code or token may leave the intended application.
The right control is not merely “validate the URL before redirecting.” The authorization server and the client must agree on the exact callback destination. OWASP's open redirect guidance explicitly recommends exact redirect-URI matching because an open redirect on the same domain could otherwise be substituted for a legitimate OAuth callback. CWE-601 examples also describe attacker-controlled paths leaking one-time exchange codes that can be converted into access tokens.
Match the complete callback
A secure OAuth policy should match the registered scheme, host, port, and path exactly. Flexible matching such as “any path on this domain” creates room for an open redirect on the same origin to receive the authorization response and forward it elsewhere.
PKCE provides an additional defense by binding the authorization code to the client that initiated the flow. It doesn't make an open redirect acceptable, and it doesn't replace exact callback registration. Teams should treat it as a layer in the protocol design, not as permission to relax redirect validation.
The review should include more than the final callback route:
- Authorization request: Confirm that redirect URIs come from registered configuration, not arbitrary request data.
- State handling: Bind state to the initiating session and avoid placing unvalidated destinations inside it.
- Code exchange: Prevent codes and tokens from appearing in referrer headers, analytics data, browser history, or intermediary pages.
- Post-callback navigation: Validate any destination used after the code exchange, even if the callback itself is fixed.
- Client routing: Inspect browser-side code for fragment or query handling that can forward identity material.
For teams evaluating how an identity product presents its login and site-building flows, an external review such as see if Auth0 uses AI builder can provide product context, but it shouldn't replace a protocol-level security review.
Design for regulated account access
In financial and health applications, a redirect defect can support account takeover rather than merely a deceptive click. The risk assessment should therefore ask whether an authorization code, access token, refresh token, session cookie, or privileged header can cross the redirect boundary.
That question belongs in design review and pull-request policy, not only in a periodic scanner run. Teams extending an identity API can also use guidance on how to protect a REST API while separately verifying callback registration, state integrity, and post-authentication navigation. The objective is continuous alignment between the intended identity flow and the code that implements it.
Testing Strategies Across Common Frameworks
Testing should begin with data flow, not with a list of favorite payloads. Identify every server redirect API, every response that sets a Location header, and every client-side navigation sink. Then trace values from query parameters, form fields, stored records, referrer-derived data, and fragments into those sinks.
For server-side checks, test the parser boundary rather than only a plain external URL. Include encoded delimiters, alternate schemes, userinfo syntax such as trusted.example@attacker.example, and parser-confusion cases. A value that passes a prefix comparison but resolves to an attacker-controlled host is exactly the class of failure the test suite must expose.
Test the representations browsers understand
Automated tests should cover:
- Host handling: Mixed-case hostnames, deceptive subdomains, userinfo syntax, and alternate ports.
- Encoding: Percent-encoded slashes, encoded backslashes, nested encoding, and fragments.
- Scheme handling:
javascript:values, unsupported schemes, and protocol-relative inputs. - Path handling: Absolute paths, double slashes, dot segments, and malformed URLs.
- Client sinks:
window.location, framework router methods, anchor assignments, and event-driven navigation.
The expected result isn't merely an error response. The application must not emit a Location header pointing to an unapproved destination, and the browser must not redirect there through client-side code.
Verify the fix in shared middleware
Put these cases in the tests for the shared redirect component, then add integration tests around login, logout, password recovery, OAuth callbacks, and account settings. Run them across each framework that implements its own routing or URL parsing. JavaScript, Java, Python, and reverse-proxy layers can normalize input differently, so a test that passes in one layer may not prove the full request path is safe.
PortSwigger recommends eliminating unnecessary redirectors or mapping a short server-side identifier to an approved destination instead of accepting complete URLs. That recommendation reduces both the number of test cases and the number of ways future code can misuse the endpoint.
A passing test suite is useful only if it remains connected to the design. Add a review requirement for new redirect parameters, callback registrations, and navigation helpers. When a developer changes an identity flow, the tests should force an explicit decision about destination ownership and token exposure.
Conclusion and Security Design Takeaways
An open redirect vulnerability is a structural design failure. The application has allowed untrusted data to make a destination decision without establishing which destinations the flow is permitted to reach.
The foundational control is destination validation. Use relative paths for same-site navigation, explicit allowlists for approved absolute destinations, and server-side identifiers when external destinations are genuinely required. Reject ambiguous URL forms, avoid arbitrary redirect parameters, and don't rely on string prefixes, blocklists, or warning pages as the primary defense.
Redirects deserve special attention in:
- Authentication and post-login routing
- Password recovery and account enrollment
- OAuth and OpenID Connect callbacks
- Logout and account-management flows
- Server-to-server requests carrying authorization headers
The engineering practice should be continuous. Model redirect behavior during architecture review, encode the approved destinations in policy, test parser edge cases in shared middleware, and verify the implementation when code and deployment configuration change. A static code review can catch a reflected parameter, but it won't necessarily detect a stored destination, a client-side router sink, or a newly added OAuth callback.
Treating redirects as security-boundary decisions changes the outcome. The implementation becomes simpler, the allowlist becomes explicit, and the team can assess whether authentication material might cross an untrusted destination before the feature reaches production.
DevArmor helps teams model redirect and identity-flow risks continuously from design artifacts, repositories, and service metadata, then enforce approved security decisions through policy-as-code on pull requests. Visit DevArmor to connect threat modeling, design reviews, and implementation verification across the software delivery lifecycle.
Table of Contents
Subscribe

