Skip to main content

Granian CVE-2026-42545

MEDIUM
Uncaught Exception (CWE-248)
2026-05-06 https://github.com/emmett-framework/granian GHSA-f5p7-9fr5-8jmj
5.9
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
5.9 MEDIUM
AV:N/AC:H/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:H/PR:N/UI:N/S:U/C:N/I:N/A:H
Attack Vector
Network
Attack Complexity
High
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:01 vuln.today
Analysis Generated
May 06, 2026 - 22:01 vuln.today
CVE Published
May 06, 2026 - 21:24 nvd
MEDIUM 5.9

DescriptionGitHub Advisory

Summary

Granian aborts a worker process if a WSGI application returns an invalid HTTP response header name or value. The WSGI response conversion path uses .unwrap() on both the header name and header value constructors, so malformed output from the application becomes a process abort instead of a handled error.

This issue requires a buggy or attacker-influenced WSGI application to emit invalid headers. It is not a parser bug in Granian's request path. The security impact is that application mistakes which should result in a 500 instead kill the worker process.

Details

https://github.com/emmett-framework/granian/blob/bdd5b0fbbb2aca6f2f4c0d2700c244d190958035/src/wsgi/io.rs#L39-L42

If either conversion fails, .unwrap() panics. In release builds Granian uses panic = "abort", so the panic terminates the worker.

Preconditions

The attacker must be able to influence a header name or value produced by the WSGI application, or the application must otherwise generate invalid headers.

Examples include:

  • a header name containing a space
  • a header value containing \r\n
  • a header value containing a null byte

These are realistic failure modes for applications that reflect user-controlled data into headers such as Location, Content Disposition, or custom response headers.

PoC

Step 1

start Granian with the PoC WSGI app

python
# app.py
def app(environ, start_response):
    path = environ.get("PATH_INFO", "/")
    if path == "/crash-name":
        headers = [("X Bad Name", "value")]
    elif path == "/crash-value":
        headers = [("Content-Type", "text/html\r\nX-Injected: evil")]
    elif path == "/crash-null":
        headers = [("X-Custom", "value\x00end")]
    else:
        start_response("200 OK", [("Content-Type", "text/plain")])
        return [b"OK - server alive\n"]

    start_response("200 OK", headers)
    return [b"This response kills the worker\n"]
bash
granian --interface wsgi app:app --host 127.0.0.1 --port 8000
Step 2

trigger the crash (any one of these is sufficient)

bash
curl http://127.0.0.1:8000/crash-name
curl http://127.0.0.1:8000/crash-value
curl http://127.0.0.1:8000/crash-null

Expected result:

  • the worker aborts after any of the crash paths
  • subsequent requests fail until the worker is restarted

Impact

  • Worker process denial of service
  • A single bad response kills one worker
  • Application bugs become process crashes instead of request-scoped failures

AnalysisAI

Granian worker process aborts when a WSGI application returns invalid HTTP response header names or values due to unhandled panic in the header conversion path. An attacker who can influence WSGI application output, such as by injecting user-controlled data into response headers like Location or Content-Disposition, can trigger worker process denial of service. The vulnerability affects Granian versions 0.2.0 through 2.7.3; patch available in version 2.7.4. Proof of concept demonstrates crashes via headers containing spaces, CRLF injection, or null bytes.

Technical ContextAI

Granian is a Rust-based ASGI/WSGI application server. The vulnerability exists in the WSGI response handling code at src/wsgi/io.rs lines 39-42, where the header name and value constructors use Rust's .unwrap() method without error handling. When a WSGI application produces invalid HTTP headers-such as header names with spaces, header values containing carriage return/line feed (CRLF) sequences, or null bytes-the constructors fail validation. In Rust, unwrap() on a failed Result panics; Granian is compiled with panic = "abort" in release builds, causing the entire worker process to terminate instead of gracefully returning a 500 error. This is fundamentally a CWE-248 (Uncaught Exception) issue where error conditions that should be handled at the application layer instead propagate as fatal process crashes. The root cause is not a parser vulnerability in Granian's request path but rather insufficient input validation in the response serialization path.

RemediationAI

Upgrade Granian to version 2.7.4 or later, which resolves the .unwrap() panic by implementing proper error handling for invalid header names and values. The patch replaces unwrap() calls with error propagation that returns a 500 Internal Server Error to the client instead of aborting the worker process. For organizations unable to immediately upgrade, the primary mitigation is to sanitize all user-controlled data before it is reflected into response headers in the WSGI application layer. Specifically, validate that header names contain only alphanumeric characters and hyphens (per RFC 7230), header values do not contain CRLF or null bytes, and consider using a header validation library in your framework (e.g., Werkzeug's Headers class for Flask applications). This mitigation does not eliminate the root cause in Granian but reduces the attack surface by preventing the malformed headers from being generated. Load-balanced deployments should monitor worker restarts and alert on excessive crashes, which may indicate application bugs or attack attempts. The advisory is available at https://github.com/advisories/GHSA-f5p7-9fr5-8jmj.

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-42545 vulnerability details – vuln.today

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