Описание
pyLoad has a Session Cookie Security Downgrade via Untrusted X-Forwarded-Proto Header Spoofing (Global State Race Condition)
Summary
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 that the request originates from a trusted proxy, then mutates the global Flask configuration SESSION_COOKIE_SECURE on every request. Because pyLoad uses the multi-threaded Cheroot WSGI server (request_queue_size=512), this creates a race condition where an attacker's request can influence the Secure flag on other users' session cookies — either downgrading cookie security behind a TLS proxy or causing a session denial-of-service on plain HTTP deployments.
Details
The vulnerable code is in src/pyload/webui/app/__init__.py:75-84:
The root cause has two components:
-
No origin validation (CWE-346): The
X-Forwarded-Protoheader is read from any client request. This header is only trustworthy when set by a known reverse proxy. WithoutProxyFixmiddleware or a trusted proxy allowlist, any client can spoof it. The code itself acknowledges this with the TODO on line 76. -
Global state mutation in a multi-threaded server:
flask.current_app.config['SESSION_COOKIE_SECURE']is application-wide shared state. When Thread A (attacker) writesFalseto this config, Thread B (victim) may readFalsewhen Flask'ssave_session()runs in the after_request phase, producing aSet-Cookieresponse without theSecureflag.
The Cheroot WSGI server is configured with request_queue_size=512 in src/pyload/webui/webserver_thread.py:46, confirming concurrent multi-threaded request processing.
No ProxyFix or equivalent middleware is configured anywhere in the codebase (confirmed via codebase-wide search).
PoC
Attack Path 1 — Cookie Security Downgrade (behind TLS-terminating proxy, use_ssl=False):
An attacker with direct access to the backend (e.g., in a containerized/Kubernetes deployment) sends concurrent requests to keep SESSION_COOKIE_SECURE set to False:
Attack Path 2 — Session Denial of Service (default plain HTTP deployment):
The second attack path works against the default configuration (use_ssl=False) and requires no special network position.
Impact
-
Session cookie exposure (Attack Path 1): When deployed behind a TLS-terminating proxy, an attacker can cause session cookies to be issued without the
Secureflag. If the victim's browser subsequently makes an HTTP request (e.g., via a mixed-content link or downgrade attack), the session cookie is transmitted in cleartext, enabling session hijacking. -
Session denial of service (Attack Path 2): On default plain HTTP deployments, an attacker can continuously set
SESSION_COOKIE_SECURE=True, causing browsers to refuse sending session cookies back to the server. This silently breaks all concurrent users' sessions with no user-visible error message, only a redirect to login. -
No authentication required: Both attack paths are fully unauthenticated — the
before_requesthandler fires before any auth checks.
Recommended Fix
Replace the global config mutation with per-response cookie handling, and add proxy validation:
At minimum, remove the before_request handler entirely and set SESSION_COOKIE_SECURE once at startup (line 130 already does this in _configure_session). The dynamic per-request adjustment is the root cause of both the spoofing and the race condition.
Пакеты
pyload-ng
<= 0.5.0b3.dev97
0.5.0b3.dev98
Связанные уязвимости
pyLoad is a free and open-source download manager written in Python. Prior to 0.5.0b3.dev98, 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 that the request originates from a trusted proxy, then mutates the global Flask configuration SESSION_COOKIE_SECURE on every request. Because pyLoad uses the multi-threaded Cheroot WSGI server (request_queue_size=512), this creates a race condition where an attacker's request can influence the Secure flag on other users' session cookies — either downgrading cookie security behind a TLS proxy or causing a session denial-of-service on plain HTTP deployments. This vulnerability is fixed in 0.5.0b3.dev98.
pyLoad is a free and open-source download manager written in Python. P ...