CVE-2026-21860: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-21860 is a vulnerability in Werkzeug's safe_join() function that improperly handles Windows reserved device names (e.g., CON, AUX, PRN, NUL, COM1–COM9, LPT1–LPT9) when they appear with file extensions or trailing spaces (e.g., CON.txt, CON.txt.html, CON ). This is a bypass of a prior incomplete fix (GHSA-hgf8-39gv-g3f2) that failed to account for compound extensions and additional special names. All Werkzeug versions prior to 3.1.5 are affected; the issue is Windows-specific and does not affect Linux/POSIX deployments. It was disclosed on January 8, 2026, with a CVSS v3.1 score of 5.3 (Medium) and a CVSS v4.0 score of 6.3 (Medium) (Github Advisory, Werkzeug Advisory).

Technical details

The root cause is CWE-67 (Improper Handling of Windows Device Names): Werkzeug's safe_join() function in src/werkzeug/security.py checked only the base name via os.path.splitext(filename)[0], which failed to strip compound extensions (e.g., CON.txt.html) or trailing spaces before comparing against the blocklist of reserved device names. The fix in version 3.1.5 changes the check to use filename.partition(".")[0].strip().upper(), correctly isolating the device name stem before any extension or whitespace. The send_from_directory() function relies on safe_join() to safely serve user-specified file paths; on Windows, if a path resolves to a device name, the OS opens it successfully but reading hangs indefinitely, causing a denial of service. The expanded blocklist in the patch also adds CONIN$, CONOUT$, and superscript-suffixed COM/LPT variants (Werkzeug Advisory, Patch Commit).

Impact

Exploitation causes an availability impact on Windows-hosted Werkzeug applications: when a request path resolves to a Windows device name, the server thread or process hangs indefinitely waiting for a read from the device, effectively causing a denial of service for that request handler. There is no confidentiality or integrity impact assessed by the CNA. Applications using send_from_directory() or any code path invoking safe_join() with user-controlled input on Windows are directly affected; downstream products including IBM Netezza Appliance, IBM QRadar Suite Software, IBM Rapid Infrastructure Automation, IBM Cloud Pak for Security, IBM watsonx Data Intelligence, and Dell Automation Platform have also been identified as affected (Github Advisory, Feedly).

Exploitability

No public proof-of-concept exploit code is known to exist, and there is no evidence of in-the-wild exploitation at this time (Github Advisory). The EPSS score is approximately 0.023% (7th percentile), indicating a low near-term exploitation probability. The vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. No threat actor attribution has been reported. Detection plugins are available via Nessus (plugin 282536) and Qualys (ID 6626575) (Feedly).

Exploitation steps

  1. Identify target: Locate a Windows-hosted web application using Werkzeug versions prior to 3.1.5 that exposes a file-serving endpoint backed by send_from_directory() or a similar function using safe_join().
  2. Craft malicious request: Construct an HTTP GET request where the filename parameter contains a Windows device name with a compound extension or trailing space, such as CON.txt, CON.txt.html, AUX.log, or CON (with trailing space).
  3. Send request: Submit the crafted request to the target endpoint (e.g., GET /files/CON.txt HTTP/1.1).
  4. Trigger hang: On Windows, the OS resolves the path to the CON device and opens it successfully; the application then attempts to read from the device, which blocks indefinitely, consuming the worker thread/process and degrading service availability.
  5. Repeat for DoS: Send multiple such requests to exhaust available worker threads, causing a sustained denial of service against the application (Werkzeug Advisory, Patch Commit).

Indicators of compromise

  • Network: HTTP GET requests to file-serving endpoints with filenames matching Windows device name patterns (e.g., CON.txt, CON.txt.html, AUX.log, NUL.dat, COM1.cfg, LPT1.txt, CON with trailing space); repeated requests from the same source IP targeting such paths.
  • Logs: Web server access logs showing requests to static file endpoints with device-name filenames returning no response or timing out; application error logs showing hung or stalled read operations on device paths.
  • Process: Worker processes or threads in a persistent blocked/waiting state associated with file read operations on Windows device paths; abnormally high number of stuck worker threads in the application process.

Mitigation and workarounds

Upgrade Werkzeug to version 3.1.5 or later, which corrects the safe_join() logic to properly strip compound extensions and trailing spaces before checking against the Windows device name blocklist (Werkzeug Advisory, Patch Commit). If immediate patching is not possible, implement additional server-side input validation to reject filenames matching Windows device name patterns before they reach safe_join(). Restricting access to file-serving endpoints or deploying a WAF rule to block requests with device-name filenames can serve as a temporary mitigation. IBM and Dell have issued separate advisories for their affected products and should be consulted for product-specific patch guidance (IBM Netezza Advisory, Feedly).

Community reactions

The vulnerability was reported by security researchers yueyueL and MushroomWasp and patched by Werkzeug maintainer davidism on January 8, 2026 (Werkzeug Advisory). Multiple downstream vendors including IBM and Dell have issued security bulletins acknowledging the impact on their products. No significant broader community controversy or media coverage has been identified beyond standard vulnerability disclosure channels.

Additional resources

Linux Distribution fix status

Fix availability across major Linux distributions and their releases.

Debian

Fixed

bookworm

python-werkzeug

Fixed

sid

python-werkzeug

Fixed

trixie

python-werkzeug

Fixed

Alpine

Fixed

edge

py3-werkzeug: 3.1.5-r0

Fixed

Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-v2f8-6655-7grjCRITICAL10
  • Python logoPython
  • vibe-trading-ai
NoYesOct 02, 2026
CVE-2026-105782HIGH7.5
  • Python logoPython
  • scrapy
NoYesOct 06, 2026
GHSA-v853-p72q-4cfwHIGH7.5
  • Python logoPython
  • quart
NoYesOct 05, 2026
CVE-2026-105751MEDIUM6.9
  • Python logoPython
  • docling
NoYesOct 05, 2026
CVE-2026-105750MEDIUM5.9
  • Python logoPython
  • docling
NoYesOct 05, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management