Improper authorization control for web services In pyload-ng

Description

pyload-ng has a WebUI JSON permission mismatch that lets ADD/DELETE users invoke MODIFY-only actions

Summary

Several WebUI JSON endpoints enforce weaker permissions than the core API methods they invoke. This allows authenticated low-privileged users to execute MODIFY operations that should be denied by pyLoad's own permission model.

Confirmed mismatches:

    ADD user can reorder packages/files (order_package, order_file) via /json/package_order and /json/link_order

    DELETE user can abort downloads (stop_downloads) via /json/abort_link

Details

pyLoad defines granular permissions in core API:

    order_package requires Perms.MODIFY (src/pyload/core/api/__init__.py:1125)

    order_file requires Perms.MODIFY (src/pyload/core/api/__init__.py:1137)

    stop_downloads requires Perms.MODIFY (src/pyload/core/api/__init__.py:1046)

But WebUI JSON routes use weaker checks:

    /json/package_order uses @login_required("ADD") then calls api.order_package(...) (src/pyload/webui/app/blueprints/json_blueprint.py:109-117)

    /json/link_order uses @login_required("ADD") then calls api.order_file(...) (src/pyload/webui/app/blueprints/json_blueprint.py:137-145)

    /json/abort_link uses @login_required("DELETE") then calls api.stop_downloads(...) (src/pyload/webui/app/blueprints/json_blueprint.py:123-131)

Why this is likely unintended (not just convenience):

    The same JSON blueprint correctly protects other edit actions with MODIFY:

      /json/move_package -> @login_required("MODIFY") (json_blueprint.py:188-196)

      /json/edit_package -> @login_required("MODIFY") (json_blueprint.py:202-217)

    The project UI exposes granular per-user permission assignment (settings.html:184-190), implying these boundaries are intended security controls.

PoC

Environment:

    Repository version: 0.5.0b3 (VERSION file)

    Commit tested: ddc53b3d7

PoC A (ADD-only user invokes MODIFY-only reorder):

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...

Observed output:

API auth (ADD-only) order_package: False
API auth (ADD-only) order_file: False
HTTP /json/package_order: 200 {"response":"success"}
HTTP /json/link_order: 200 {"response":"success"}
calls: [('order_package', 5, 0), ('order_file', 77, 1)]

PoC B (DELETE-only user invokes MODIFY-only stop_downloads):

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...

Observed output:

API auth (DELETE-only) stop_downloads: False
HTTP /json/abort_link: 200 {"response":"success"}
calls: [('stop_downloads', [999])]

Impact

Type:

    Improper authorization / permission-bypass between WebUI and core API permission model.

Scope:

    Horizontal privilege escalation among authenticated non-admin users.

    Not admin takeover, but unauthorized execution of operations explicitly categorized as MODIFY.

Security impact:

    Integrity impact: unauthorized queue/file reordering by users lacking MODIFY.

    Availability impact: unauthorized abort of active downloads by users lacking MODIFY.

Mitigation

Update Impact

Minimal update. May introduce new vulnerabilities or breaking changes.

Ecosystem
Package
Affected version