CVE-2026-40594
Python vulnerability analysis and mitigation

Overview

CVE-2026-40594 is a session cookie security downgrade vulnerability in pyload-ng caused by untrusted X-Forwarded-Proto header spoofing combined with a global state race condition. The set_session_cookie_secure before_request handler in src/pyload/webui/app/__init__.py reads the X-Forwarded-Proto header from any HTTP request without validating its origin, then mutates the global Flask SESSION_COOKIE_SECURE configuration on every request. Affected versions are pyload-ng <= 0.5.0b3.dev97 (pip); the patched version is 0.5.0b3.dev98. Disclosed on April 14, 2026 by researcher GammaC0de and published to the GitHub Advisory Database on April 16, 2026, it carries a CVSS v3.1 base score of 4.8 (Medium) (GitHub Advisory, pyload Advisory).

Technical details

The root cause is twofold and classified as CWE-346 (Origin Validation Error). First, the X-Forwarded-Proto header is accepted from any client without verifying it originates from a trusted reverse proxy — the code even contains a # TODO: Add trusted proxy check comment acknowledging this gap. Second, the handler writes the derived boolean directly to flask.current_app.config['SESSION_COOKIE_SECURE'], which is application-wide shared state; because pyLoad uses the multi-threaded Cheroot WSGI server (request_queue_size=512), an attacker's thread can overwrite this value between the time a victim's request is processed and Flask's save_session() runs in the after_request phase, producing a Set-Cookie header with the wrong Secure flag. No ProxyFix or equivalent middleware is present anywhere in the codebase (GitHub Advisory, pyload Advisory).

Impact

There are two distinct impact scenarios, both requiring no authentication. In deployments behind a TLS-terminating proxy, an attacker with direct backend access can flood the server with X-Forwarded-Proto: http requests, causing concurrent legitimate users to receive session cookies without the Secure flag; those cookies can then be intercepted over plain HTTP, enabling session hijacking. In default plain-HTTP deployments, an attacker can flood with X-Forwarded-Proto: https, setting SESSION_COOKIE_SECURE=True so browsers refuse to transmit cookies over HTTP, silently breaking all concurrent users' sessions and forcing repeated logouts (session denial-of-service) (GitHub Advisory, pyload Advisory).

Exploitability

A proof-of-concept consisting of concrete, runnable bash curl commands is publicly available in the GitHub Security Advisory and was assessed with high confidence by Feedly threat intelligence. No authentication is required for either attack path, and no special privileges are needed. As of the time of reporting, there is no evidence of in-the-wild exploitation and no CISA KEV catalog entry. The EPSS score is approximately 0.011% (1st percentile), indicating low current exploitation probability (pyload Advisory, GitHub Advisory).

Exploitation steps

  1. Reconnaissance: Identify internet-facing or internally accessible pyLoad instances running pyload-ng <= 0.5.0b3.dev97, particularly those deployed behind a TLS-terminating reverse proxy (e.g., nginx, Traefik) in containerized/Kubernetes environments.
  2. Determine deployment mode: Probe whether the backend is directly reachable (bypassing the TLS proxy) by sending a plain HTTP request to the backend port (default 8000). If accessible, Attack Path 1 (cookie downgrade) is viable; if only plain HTTP is used end-to-end, Attack Path 2 (session DoS) applies.
  3. Attack Path 1 — Cookie Security Downgrade: Send a high volume of concurrent HTTP requests with a spoofed X-Forwarded-Proto: http header directly to the backend, keeping SESSION_COOKIE_SECURE set to False during the race window:
    for i in $(seq 1 200); do curl -s -H 'X-Forwarded-Proto: http' http://pyload-backend:8000/ & done
  4. Race window exploitation: While the attacker's flood is active, a legitimate user authenticates through the TLS proxy. Flask's save_session() reads the globally-mutated SESSION_COOKIE_SECURE=False and issues a Set-Cookie header without the Secure flag.
  5. Session hijacking: The victim's browser sends the unprotected session cookie over any subsequent HTTP request (e.g., mixed-content, HTTP redirect), allowing the attacker to intercept it via network sniffing or a man-in-the-middle position.
  6. Attack Path 2 — Session DoS: On plain HTTP deployments, flood with X-Forwarded-Proto: https to set SESSION_COOKIE_SECURE=True, causing browsers to refuse sending cookies over HTTP and silently breaking all concurrent sessions:
    for i in $(seq 1 200); do curl -s -H 'X-Forwarded-Proto: https' http://localhost:8000/ & done
    (pyload Advisory, GitHub Advisory)

Indicators of compromise

  • Network: High volume of concurrent HTTP requests to the pyLoad backend (port 8000 by default) from a single source IP, particularly with X-Forwarded-Proto: http or X-Forwarded-Proto: https headers set by a non-proxy client; direct connections to the backend port bypassing the configured TLS reverse proxy.
  • Logs: Web server access logs showing rapid, repeated GET requests to / or other pyLoad endpoints from the same IP with X-Forwarded-Proto headers; unusual spikes in request concurrency (hundreds of requests in seconds from one source).
  • Application Behavior: Legitimate users experiencing sudden session invalidation or being redirected to the login page without explicit logout action, particularly during periods of high concurrent request activity; Set-Cookie responses observed without the Secure attribute on HTTPS-proxied deployments. (pyload Advisory)

Mitigation and workarounds

Update pyload-ng to version 0.5.0b3.dev98 or later, which is the patched release addressing this vulnerability. As a workaround prior to patching, remove the set_session_cookie_secure before_request handler entirely and set SESSION_COOKIE_SECURE once at application startup (the _configure_session function at line 130 already performs this). For proxy-aware deployments, configure Werkzeug's ProxyFix middleware with an explicit trusted proxy count (ProxyFix(app.wsgi_app, x_proto=<count>)) so that X-Forwarded-Proto is only trusted from known upstream proxies. Additionally, restrict direct network access to the pyLoad backend port so that only the trusted reverse proxy can reach it (GitHub Advisory, pyload Advisory).

Community reactions

The vulnerability was reported by researcher GammaC0de and published via GitHub's coordinated disclosure process. The advisory includes a detailed recommended fix with two implementation options, suggesting constructive engagement between the reporter and the pyLoad maintainers. No significant broader media coverage or notable external researcher commentary beyond the advisory itself has been identified at this time (GitHub Advisory).

Additional resources


SourceThis report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-61539CRITICAL10
  • Python logoPython
  • xinference
NoYesAug 21, 2026
CVE-2026-49360HIGH7.8
  • Python logoPython
  • recce
NoYesAug 21, 2026
CVE-2026-68508HIGH7.8
  • Python logoPython
  • hydra-core
NoYesAug 21, 2026
CVE-2026-54457HIGH7.7
  • Python logoPython
  • tensorzero
NoYesAug 21, 2026
CVE-2026-43980MEDIUM6.3
  • Python logoPython
  • malla
NoNoAug 21, 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