Insecure object reference In pyload-ng

Description

pyLoad Has Incomplete Fix for CVE-2026-33509 -storage_folder Bypass via Session Directory in pyLoad

Summary

The fix for CVE-2026-33509 prevents setting storage_folder inside PKGDIR or userdir, but does NOT protect the Flask session directory (/tmp/pyLoad/flask). An authenticated attacker can set storage_folder to the session directory and download session files of other users via /files/get/, leading to account takeover.

Details

The fix in src/pyload/core/api/__init__.py:

directories = [PKGDIR, userdir]
if any(directories[0].startswith(d) for d in directories[1:]):
    return  # blocked

But the Flask session directory is:

session_storage_path = os.path.join(api.get_cachedir(), "flask")
# = /tmp/pyLoad/flask  ← NOT blocked by fix

Attack Chain

    Attacker (admin) sets storage_folder = /tmp/pyLoad/flask

    Fix does NOT block this — /tmp/pyLoad/flask not inside PKGDIR or userdir

    Attacker requests GET /files/get/<victim_session_filename>

    send_from_directory('/tmp/pyLoad/flask', session_file) serves victim's session

    Attacker uses stolen session → Account Takeover

PoC

POC
import os

PKGDIR = "/usr/lib/python3/dist-packages/pyload"
userdir = os.path.expanduser("~/.pyload")
session_dir = "/tmp/pyLoad/flask"

correct_case = lambda x: x
directories = [...

Impact

Authenticated admin can steal sessions of other users → Account Takeover.

Suggested Fix

blocked_dirs = [PKGDIR, userdir, api.get_cachedir()]
directories = [
    os.path.join(os.path.realpath(d), "")
    for d in [value] + blocked_dirs
]
if any(directories[0].startswith(d) for d in directories[1:]):
    return

Mitigation

Update Impact

Minimal update. May introduce new vulnerabilities or breaking changes.

Ecosystem
Package
Affected version