~/f4n6 $ grep -r "Flask-Security has an Open Redirect issue" ./investigations/ --include="*.md"

Flask-Security has an Open Redirect issue

Jeff Davies 24 Jun 2026 5 min read

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

  1. Reconnaissance: Attacker identifies a Flask application using Flask-Security with SECURITY_REDIRECT_ALLOW_SUBDOMAINS = True and SERVER_NAME set to a known domain (e.g., whitelist.com).
  2. Craft payload: Attacker constructs a URL containing a backslash in the authority component, e.g., http://evil.com\.whitelist.com or http://evil.com%5C.whitelist.com.
  3. Delivery: Attacker distributes the URL via phishing email, SMS, or social media, leveraging the trusted domain in the URL string to bypass user suspicion.
  4. Validation bypass: When the Flask application calls validate_redirect_url(next_url), Python's urlsplit() parses the full authority as evil.com\.whitelist.com or evil.com%5C.whitelist.com. Because the parsed value ends with .whitelist.com, the function accepts it as an allowed subdomain of whitelist.com.
  5. Redirect execution: The application issues a 302 redirect to the attacker-controlled URL-like authority. Browsers interpret the backslash as a path separator and navigate to evil.com, displaying attacker-controlled content under the trusted domain's URL bar context.
  6. 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.com
  • http://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: 302 redirect 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 = True and SECURITY_REDIRECT_ALLOW_SUBDOMAINS: True.
  • If the feature is not actively required, immediately set SECURITY_REDIRECT_ALLOW_SUBDOMAINS = False or remove the configuration directive.
  • Deploy WAF / reverse proxy rules to block or strip backslash (\) and percent-encoded backslash (%5C / %5c) characters in the next, 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_SUBDOMAINS or SECURITY_REDIRECT_BASE_DOMAIN with 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 to validate_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.


Read the original source →

Published via PulseTrace — Adverse Trace threat intelligence.

Post this to LinkedIn
Formatting is converted automatically — headings, bullets, a link back & hashtags. Paste straight in.
J
Jeff Davies