CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-JQ7H-WRVP-3RGX

GHSA-JQ7H-WRVP-3RGX: Insufficient Session Invalidation in pyLoad Core REST API

Amit Schendel
Amit Schendel
Senior Security Researcher

Oct 9, 2026·4 min read·6 visits

Executive Summary (TL;DR)

Administrative changes via the pyLoad REST API (such as password changes or permission downgrades) do not invalidate active filesystem-based Flask sessions. Affected users retain their original high-privilege permissions for the entire session lifetime (up to 31 days) unless sessions are manually purged.

An insufficient session invalidation vulnerability exists in pyLoad (pyload-ng) versions 0.5.0b3.dev98 through 0.5.0b3.dev101. When administrative actions like privilege revocation or password changes are executed via the public REST API, active user sessions on disk are not updated or invalidated. Consequently, affected sessions remain fully authenticated with stale permissions for up to 31 days.

Vulnerability Overview

pyLoad utilizes a Flask-based web interface to expose configuration, download management, and user controls. To reduce database overhead during client requests, pyLoad caches security credentials—such as the user's role identifier and permission bitmask—directly inside the filesystem-backed Flask session when a user first authenticates.

This design introduces a critical trust-boundary problem. The cached session data acts as the absolute source of truth for subsequent authorization decisions, bypassing real-time database validation. The primary security vulnerability, tracked under GHSA-JQ7H-WRVP-3RGX, stems from a complete lack of synchronization between administrative updates performed via the backend REST API/RPC layer and these cached session structures.

Root Cause Analysis

The root cause of this flaw is insufficient session invalidation (CWE-613). When administrators interact with pyLoad's Web UI administration panel, the application explicitly coordinates state changes, calling helper functions like clear_all_user_sessions(username) to force deletion of associated filesystem cookies.

However, pyLoad also exposes a direct REST API and RPC dispatcher (/api/) handled by the module src/pyload/core/api/__init__.py. When administrative tasks are executed via these RPC endpoints—including user deletion, privilege modification, or password alterations—the system directly updates the backend SQLite database but has no logical awareness of the active Flask session manager layer.

Consequently, database records reflect the updated privileges, but the corresponding .sess files stored inside SESSION_FILE_DIR remain active, unexpired, and intact. Because parse_permissions() continues reading authorization bits directly from the stale cookie session, affected clients preserve high-privilege access for the duration of the session's active lifespan, which defaults to 31 days.

Architectural Data Flow Diagram

The sequence below illustrates the communication breakdown between the Core API layer, SQLite database, and Web UI Session Files, culminating in unauthorized persistent access:

This architectural separation prevents the database-level modifications from propagating to active transport-layer sessions, creating a vulnerability window of up to 31 days.

Code Analysis and Patch Walkthrough

Before the patch, core user configuration methods had no references to Flask-layer sessions. To resolve this, the patch introduces a callback registration mechanism allowing the core API to request session invalidation safely.

# File: src/pyload/core/api/__init__.py (Post-patch)
def __init__(self, core):
    # ...
    self._session_invalidator = None
 
def set_session_invalidator(self, invalidator: Optional[Callable[[str], int]]) -> None:
    self._session_invalidator = invalidator
 
def _invalidate_user_sessions(self, user: str) -> None:
    if self._session_invalidator is not None:
        # Invokes the lambda registered by the Web UI layer
        self._session_invalidator(user)

The Web UI initializes this callback during web application configuration:

# File: src/pyload/webui/app/__init__.py
api = app.config["PYLOAD_API"]
api.set_session_invalidator(lambda user: clear_all_user_sessions(user))

Any critical user updates within the Core API are then wrapped to trigger the callback upon successful database execution:

# File: src/pyload/core/api/__init__.py
@legacy("setUserPermission")
@post
def set_user_permission(self, user: str, permission: int, role: int) -> None:
    # Database change operation returned boolean status
    changed = self.pyload.db.set_user_permission(user, permission, role)
    if changed:
        self._invalidate_user_sessions(user)

Attack Exploitation Methodology

An attacker must establish or compromise a valid cookie-authenticated session before privilege changes or password changes are made.

Once an administrative action is taken via the RPC API—for example, resetting a compromised user's password or reducing their user level to 1—the attacker can test persistence by making direct API calls targeting administrative features, such as get_userdir or get_config.

Because the underlying Flask framework authorizes the request using the existing filesystem session token, the client session is deemed authentic. No request middleware cross-references the session's cached values with the current DB table, maintaining administrative privileges for the lifetime of the session.

Patch Completeness Assessment

While the registered callback mechanism successfully fixes the structural bypass, security engineers should monitor two specific implementation aspects.

First, inside clear_all_user_sessions in src/pyload/webui/app/helpers.py, the removal of the general try-except structure during directory parsing introduces a minor robustness issue. If a concurrent request removes a session file, or if a zero-byte session file exists on disk, _read_session_file or os.remove will raise an unhandled exception. This will abort execution mid-loop, resulting in a server error (HTTP 500) and leaving other target user sessions still active.

Second, the synchronization is wholly dependent on the runtime environment registering the Flask configuration callback. If the application is launched in an embedded context without executing _configure_session(), the callback pointer remains None, leaving the API-level methods without any functional session invalidation capabilities.

Official Patches

pyLoadOfficial fix commit implementing API-level session invalidation callbacks.

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H

Affected Systems

pyLoad (pyload-ng) Web UI & REST API

Affected Versions Detail

Product
Affected Versions
Fixed Version
pyload-ng
pyload
>= 0.5.0b3.dev98, <= 0.5.0b3.dev101Commit 3e726ba271a6b1015e3a0ea6dc7e46a8f71a62ad
AttributeDetail
CWE IDCWE-613
Attack VectorNetwork
CVSS Score7.5
Exploit StatusProof of Concept available
ImpactPrivilege Escalation / Persistent Session Hijack

MITRE ATT&CK Mapping

T1563Subvert Active Sessions
Defense Evasion
T1098Account Manipulation
Persistence
CWE-613
Insufficient Session Invalidation

The application does not invalidate a session when the user's password or privilege level is modified via the API dispatcher.

References & Sources

  • [1]GitHub Security Advisory GHSA-jq7h-wrvp-3rgx
  • [2]GitHub Security Advisory GHSA-889w-m37p-88m5
  • [3]Fix Commit 3e726ba
  • [4]pyLoad GitHub Repository
Related Vulnerabilities
GHSA-889w-m37p-88m5

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 3 hours ago•GHSA-9Q47-3CM2-2RP8
6.5

GHSA-9Q47-3CM2-2RP8: Rate-Limit Bypass and Audit Log Spoofing in pyLoad WebUI

A critical security vulnerability has been identified and patched in the WebUI component of pyLoad, a popular Python-based open-source download manager. This vulnerability allows attackers to completely bypass API rate limits and spoof client IP addresses in audit logs due to unsafe parsing of the X-Forwarded-For HTTP header.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 4 hours ago•GHSA-68W4-83FH-F2W8
8.8

GHSA-68W4-83FH-F2W8: Privilege Escalation and Administrative Password Oracle in pyLoad-ng

An authorization bypass and credential oracle vulnerability in pyload-ng allows authenticated users with minimal or no privileges to brute-force the administrator password. This is achieved through sensitive API methods exposed globally combined with a non-constant-time password hash comparison algorithm.

Alon Barad
Alon Barad
8 views•7 min read
•about 5 hours ago•GHSA-R44W-V6GF-X3P6
8.1

Authentication Bypass in pyLoad API Key Caching Mechanism (GHSA-R44W-V6GF-X3P6)

An authentication bypass vulnerability in pyLoad allows unauthenticated remote attackers to gain administrative API access. The vulnerability is caused by a logical flaw in the API key cache validation lookup, where authentication states are cached using only the public key identifier, skipping cryptographic token verification on cache hits.

Alon Barad
Alon Barad
10 views•7 min read
•about 6 hours ago•CVE-2026-107728
7.5

CVE-2026-107728: Authorization Bypass in Strawberry GraphQL Permission Validation

An authorization bypass vulnerability in Strawberry GraphQL between versions 0.217.0 and 0.326.1 occurs when a synchronous permission handler returns an awaitable object (such as an unawaited coroutine). Due to Python's truthiness rules, the unawaited coroutine is evaluated as True, leading to an immediate bypass of security policies.

Amit Schendel
Amit Schendel
9 views•5 min read
•about 7 hours ago•CVE-2026-107727
3.7

CVE-2026-107727: Connection-Level Denial of Service via State Leak in Strawberry GraphQL Legacy WS Handler

An uncontrolled resource consumption vulnerability in Strawberry GraphQL allows unauthenticated remote attackers to trigger a Denial of Service on persistent WebSocket connections using the legacy graphql-ws protocol. When the server enforces max_subscriptions_per_connection, naturally terminating subscriptions are not cleared from memory registries, leading to exhaustion of connection slots.

Alon Barad
Alon Barad
12 views•6 min read
•about 8 hours ago•CVE-2026-107723
8.1

CVE-2026-107723: Silent Claim-Validator Bypass in NearForm fast-jwt via Array Payload Type Confusion

A high-severity type-confusion vulnerability exists in NearForm fast-jwt prior to version 6.3.0. The vulnerability allows attackers to bypass crucial claim validation steps (such as expiration, issuer, audience, and subject validations) by presenting a validly signed JSON Web Token structured as a JSON array instead of a JSON object. This occurs because the library's decoder fails to reject JSON arrays during type evaluation.

Alon Barad
Alon Barad
11 views•6 min read