1. Executive summary
A vulnerability in the flask_security.utils.validate_redirect_url() function allows an attacker to bypass redirect URL validation when subdomain matching is enabled, producing a 302 redirect to an attacker-controlled destination. The bypass uses a literal backslash (\) or percent-encoded backslash (%5C) inside the URL authority (e.g., http://evil.com\.whitelist.com), which Python's urlsplit() parses as a single hostname ending in .whitelist.com, causing the validator to accept it as a legitimate subdomain. The issue is tracked under GHSA-w2j7-f3c6-g8cw and is similar in class to the previously disclosed CVE-2023-49438 (CVSS unknown, not in CISA KEV). EMEA financial services entities running Flask-based applications — including customer-facing banking portals, fintech APIs, and internal admin tools — that use Flask-Security with SECURITY_REDIRECT_ALLOW_SUBDOMAINS = True are exposed to phishing and credential-harvesting attacks leveraging trusted-domain redirects.
2. Regulatory framing
| Article | Trigger (the fact in this item) | Practical impact |
|---|---|---|
| DORA Art. 28 — ICT third-party risk — general principles | Flask-Security is a third-party ICT component embedded in financial entities' web applications. | Financial entities must identify Flask-Security in their ICT third-party register, assess the residual risk of this open-redirect vulnerability, and ensure remediation is tracked within vendor risk management processes. |
| NIS2 Art. 21(2)(d) — supply chain security measures | The vulnerability resides in a widely-used open-source library (Flask-Security) that forms part of the software supply chain for in-scope essential and important entities. | In-scope entities must evaluate the vulnerability across their Flask-based applications, apply mitigations, and document the assessment as part of supply-chain security obligations. |
| UK NIS 2018 — OES/RDSP duties | Operators of Essential Services and Relevant Digital Service Providers running Flask-based services with affected configurations fall within scope. | Affected OES/RDSPs must assess exposure, apply mitigations, and record the response within their security risk management duties. |
3. Technical analysis & attack chain
- Reconnaissance: Attacker identifies a Flask application using Flask-Security with
SECURITY_REDIRECT_ALLOW_SUBDOMAINS = TrueandSERVER_NAMEset to a known domain (e.g.,whitelist.com). - Craft payload: Attacker constructs a URL containing a backslash in the authority component, e.g.,
http://evil.com\.whitelist.comorhttp://evil.com%5C.whitelist.com. - Delivery: Attacker distributes the URL via phishing email, SMS, or social media, leveraging the trusted domain in the URL string to bypass user suspicion.
- Validation bypass: When the Flask application calls
validate_redirect_url(next_url), Python'surlsplit()parses the full authority asevil.com\.whitelist.comorevil.com%5C.whitelist.com. Because the parsed value ends with.whitelist.com, the function accepts it as an allowed subdomain ofwhitelist.com. - Redirect execution: The application issues a
302redirect to the attacker-controlled URL-like authority. Browsers interpret the backslash as a path separator and navigate toevil.com, displaying attacker-controlled content under the trusted domain's URL bar context. - Exploitation: Victim lands on attacker-controlled page, which may host phishing forms, credential harvesters, or malware payloads.
Technical specifics
- Vulnerable function:
flask_security.utils.validate_redirect_url() - Trigger configuration:
SERVER_NAME = "whitelist.com"SECURITY_REDIRECT_ALLOW_SUBDOMAINS = True- Tested environment: Flask-Security 5.8.0, Flask 3.1.3, Werkzeug 3.1.8
- Bypass payloads:
http://evil.com\.whitelist.comhttp://evil.com%5C.whitelist.com- Root cause:
urlsplit()does not normalize or reject backslash characters in the authority component. The validator performs a substring check (.endswith(".whitelist.com")) without validating that the hostname is a true subdomain. - HTTP response:
302redirect to the attacker-controlled authority. - Related CVE: CVE-2023-49438 (CVSS unknown, not in CISA KEV) — previous Flask-Security-Too open redirect advisory with similar browser URL normalization bypass behavior.
Unconfirmed / single-sourced claims: The source material does not specify whether a vendor patch has been released. The advisory references CVE-2023-49438 as a "previous" similar issue; the current advisory (GHSA-w2j7-f3c6-g8cw) does not have a separately assigned CVE in the provided material. No threat actor attribution is provided; any attribution would be unconfirmed.
4. Mitigation & containment
P1 — Within 24 hours (containment)
- Audit all Flask applications for the vulnerable configuration. Search codebase and configuration management for
SECURITY_REDIRECT_ALLOW_SUBDOMAINS = TrueandSECURITY_REDIRECT_ALLOW_SUBDOMAINS: True. - If the feature is not actively required, immediately set
SECURITY_REDIRECT_ALLOW_SUBDOMAINS = Falseor remove the configuration directive. - Deploy WAF / reverse proxy rules to block or strip backslash (
\) and percent-encoded backslash (%5C/%5c) characters in thenext,redirect,url,return_url, and similar query parameters used for redirects. - Review web server access logs and application logs for requests matching the bypass patterns (
\.whitelist.com,%5C.whitelist.com, or any backslash in redirect parameters) over the past 90 days.
P2 — Within 72 hours (remediation)
- Replace open-ended subdomain matching with an explicit allowlist using
SECURITY_REDIRECT_ALLOWED_SUBDOMAINSorSECURITY_REDIRECT_BASE_DOMAINwith a defined list of permitted subdomains. - Implement application-level input validation in redirect handlers to reject URLs containing backslash characters (
\,%5C,%5c) in the authority component before passing tovalidate_redirect_url(). - Pin Flask-Security to a patched version once available; monitor the Flask-Security GitHub repository and PyPI page for security releases addressing GHSA-w2j7-f3c6-g8cw.
P3 — Within 7 days (hardening)
- Conduct a full inventory of all Flask-Security dependencies across the estate using software composition analysis (SCA) tools.
- Document the vulnerability and remediation in the ICT third-party risk register per DORA Art. 28 obligations.
- Review and update secure coding guidelines to prohibit substring-based hostname validation in favour of proper URL parsing and hostname comparison.
5. Indicators of compromise
| Type | Value | Confidence | Source |
|---|---|---|---|
| url-pattern | http://*.whitelist.com containing \ or %5C in authority |
High | GHSA-w2j7-f3c6-g8cw |
| url-pattern | http://*.whitelist.com containing %5C in authority |
High | GHSA-w2j7-f3c6-g8cw |
url-pattern http://*.whitelist.com containing \ or %5C in authority
url-pattern http://*.whitelist.com containing %5C in authority
6. Detection
rule Flask_Security_Open_Redirect_Bypass_PoC
{
meta:
author = "Adverse Trace"
date = "2026-06-24"
reference = "https://github.com/advisories/GHSA-w2j7-f3c6-g8cw"
description = "Detects Flask-Security open redirect bypass PoC code and exploit payloads"
strings:
$func = "validate_redirect_url"
$config1 = "SECURITY_REDIRECT_ALLOW_SUBDOMAINS"
$config2 = "SECURITY_REDIRECT_BASE_DOMAIN"
$config3 = "SECURITY_REDIRECT_ALLOWED_SUBDOMAINS"
$payload1 = "evil.com\\.whitelist.com"
$payload2 = "evil.com%5C.whitelist.com"
$poc_route = "/redir"
$poc_param = "next="
condition:
$func and any of ($config*) and any of ($payload*) or
$func and any of ($config*) and $poc_route and $poc_param
}
title: Flask-Security Open Redirect Bypass Attempt
id: AT-2026-06-24-154
status: experimental
description: Detects HTTP requests containing backslash characters in redirect parameters targeting Flask-Security applications
author: Adverse Trace
date: 2026-06-24
reference: https://github.com/advisories/GHSA-w2j7-f3c6-g8cw
logsource:
category: webserver
detection:
selection_backslash_literal:
cs-uri-query|contains: '\.whitelist.com'
selection_backslash_encoded:
cs-uri-query|contains: '%5C.whitelist.com'
cs-uri-query|contains: '%5c.whitelist.com'
filter_legitimate:
cs-uri-query|contains: 'evil.com'
condition: selection_backslash_literal or selection_backslash_encoded
fields:
- cs-uri-query
- cs-host
- c-ip
falsepositives:
- Legitimate URLs containing backslash in path components (uncommon)
level: high
CVE assessment
1 referenced CVE
| CVE | CVSS | Exploited | EPSS | Summary |
|---|---|---|---|---|
| CVE-2023-49438 | — | — | — |
7. Sources
- GitHub Advisory Database — GHSA-w2j7-f3c6-g8cw: Flask-Security has an Open Redirect issue — https://github.com/advisories/GHSA-w2j7-f3c6-g8cw — 2026-06-23
- GitLab Advisory Database — CVE-2023-49438 (previous similar advisory) — https://advisories.gitlab.com/pypi/flask-security-too/CVE-2023-49438/
- OSV — CVE-2023-49438 — https://osv.dev/vulnerability/CVE-2023-49438
- NVD — CVE-2023-49438 — https://nvd.nist.gov/vuln/detail/CVE-2023-49438
8. Adverse Trace position
Severity: Moderate. The vulnerability enables phishing attacks via trusted-domain redirects but requires specific configuration (SECURITY_REDIRECT_ALLOW_SUBDOMAINS = True) and user interaction (clicking a crafted link). No code execution or data exfiltration is directly enabled; impact is limited to social engineering and credential harvesting. CVE-2023-49438 is not in CISA KEV and has no published CVSS score, indicating no known active exploitation at this time. Client impact: EMEA financial services entities running Flask-based customer-facing or internal applications with subdomain-based redirect validation enabled should treat this as a P1 containment item pending vendor patch availability. Next steps: Adverse Trace will monitor for a vendor patch release and update this advisory accordingly. Clients requiring assistance with inventory, WAF rule deployment, or remediation should contact the Adversary Trace incident response team.
Published via PulseTrace — Adverse Trace threat intelligence.