CVE-2026-21883: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-21883 is a Cross-Site WebSocket Hijacking (CSWSH) vulnerability in Bokeh, an interactive Python visualization library, caused by incomplete origin validation in WebSocket connections. It affects all Bokeh versions prior to 3.8.2 (specifically 3.8.1 and below) when deployed as a server instance with an origin allowlist configured. The vulnerability was published on January 6, 2026, and patched in version 3.8.2. It carries a CVSS v3.1 base score of 5.4 (Medium) and a CVSS v4.0 base score of 4.5 (Medium) (Github Advisory, Bokeh Security Advisory).

Technical details

The root cause is a logic flaw in the match_host function within src/bokeh/server/util.py, classified as CWE-1385 (Missing Origin Validation in WebSockets). The function uses Python's zip() to compare hostname parts against allowlist pattern parts; however, zip() stops iteration when the shortest iterable is exhausted. Because the code only checks whether the pattern is longer than the host — but not the reverse — a hostname that begins with the allowlisted pattern but contains additional segments (e.g., example.com.attacker.com matching against example.com) is incorrectly accepted. An attacker exploits this by registering a domain that starts with an allowlisted domain name, hosting a malicious page there, and having that page initiate a WebSocket connection to the vulnerable Bokeh server with a crafted Origin header that passes the flawed validation (Bokeh Security Advisory, Github Advisory). A public technical write-up and proof-of-concept are available at https://aydinnyunus.github.io/2026/01/24/bokeh-websocket-hijacking-cve-2026-21883/.

Impact

Successful exploitation enables an attacker to establish an unauthorized WebSocket session to a Bokeh server on behalf of a victim user, allowing access to sensitive data displayed in Bokeh visualizations and the ability to modify visualizations or perform other operations within the victim's session context. The vulnerability has no impact on availability, and does not affect static HTML output, standalone embedded plots, Jupyter notebook usage, or Bokeh servers deployed on private internal networks. It also cannot bypass up-front authentication hooks if those are configured on the server (Bokeh Security Advisory, Github Advisory).

Exploitability

Proof-of-concept exploit code and a technical write-up are publicly available, referenced in the GitHub Advisory and attributed to researcher aydinnyunus (Github Advisory). Exploitation requires user interaction — the victim must visit an attacker-controlled domain — but requires no special privileges from the attacker. There is no confirmed evidence of in-the-wild exploitation at this time, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. The EPSS score is approximately 0.019% (2nd percentile), indicating a low probability of near-term exploitation (Github Advisory).

Exploitation steps

  1. Reconnaissance: Identify publicly accessible Bokeh server instances (version ≤ 3.8.1) using tools like Shodan or Censys, or target a known deployment. Determine the configured origin allowlist domain (e.g., dashboard.corp).
  2. Register a matching domain: Register a domain that begins with the allowlisted pattern, such as dashboard.corp.attacker.com, which will pass the flawed zip()-based hostname comparison.
  3. Host a malicious page: Set up a web page on the attacker-controlled domain containing JavaScript that initiates a WebSocket connection to the target Bokeh server (e.g., ws://bokeh-server.corp:5006/ws).
  4. Social engineer the victim: Lure the victim into visiting the malicious page (e.g., via phishing email or link), causing their browser to send a WebSocket upgrade request with the Origin: http://dashboard.corp.attacker.com header.
  5. Bypass origin validation: The Bokeh server's match_host function compares dashboard.corp.attacker.com against the allowlisted dashboard.corp using zip(), which only checks the first two parts (dashboard dashboard, corp corp) and returns True, accepting the connection.
  6. Hijack the session: With the WebSocket connection established in the victim's browser context, the attacker's JavaScript can interact with the Bokeh server on behalf of the victim — reading sensitive visualization data or sending commands to modify server-side state (Bokeh Security Advisory, Github Advisory).

Indicators of compromise

  • Network: WebSocket upgrade requests to the Bokeh server (/ws endpoint) with Origin headers that contain the allowlisted domain as a prefix but include additional subdomains or segments (e.g., Origin: http://dashboard.corp.attacker.com).
  • Network: Unexpected WebSocket connections originating from unfamiliar or external IP addresses that do not correspond to known legitimate client networks.
  • Logs: Bokeh server access logs showing WebSocket connections accepted from Origin values that are longer than the configured allowlist entries (e.g., allowlist entry dashboard.corp but origin logged as dashboard.corp.external.com).
  • Logs: Unusual patterns of data access or visualization modification events in Bokeh server logs correlated with WebSocket sessions from suspicious origins.

Mitigation and workarounds

Upgrade Bokeh to version 3.8.2 or later, which corrects the match_host function to properly validate that the host is not longer than the allowlist pattern (Bokeh Security Advisory, Patch Commit). No official workaround exists in the vulnerable versions; however, as interim mitigations, operators should implement network-level controls (e.g., firewall rules or reverse proxy configurations) to restrict WebSocket connections to trusted source IPs, and monitor WebSocket connection logs for suspicious Origin headers. Users should also be educated to avoid clicking links to unfamiliar domains that may resemble internal application URLs.

Community reactions

The vulnerability was reported by researcher aydinnyunus, who published a technical write-up and proof-of-concept at https://aydinnyunus.github.io/2026/01/24/bokeh-websocket-hijacking-cve-2026-21883/, and was coordinated by katzj from the Bokeh project (Github Advisory). The Bokeh maintainer bryevdv published the security advisory and patch on January 6, 2026. General community coverage appeared on vulnerability aggregation platforms including CVEFeed, VulnDB, and INCIBE-CERT shortly after disclosure.

Additional resources


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