VAITP Dataset

← Back to the dataset

CVE-2026-44226

pyLoad WebUI leaks Python stack traces to unauthenticated users.

  • CVSS 5.3
  • CWE-209
  • Information Leakage
  • Remote

pyLoad is a free and open-source download manager written in Python. Prior to 0.5.0b3.dev100, pyload-ng WebUI returns full Python traceback details to clients on unhandled exceptions. Because /web/<path:filename> is reachable without authentication and renders attacker-controlled template names, an unauthenticated user can reliably trigger a server exception (for example by requesting a non-existent template) and receive internal stack traces in the HTTP response. This vulnerability is fixed in 0.5.0b3.dev100.

CVSS base score
5.3
Published
2026-05-11
OWASP
A05 Security Misconfiguration
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Information Leakage
Subcategory
Information Disclosure
Accessibility scope
Remote
Impact
Information Disclosure
Affected component
pyLoad
Fixed by upgrading
Yes

Solution

Upgrade pyLoad to version 0.5.0b3.dev100 or later.

Vulnerable code sample

from flask import Flask, render_template
from jinja2.exceptions import TemplateNotFound

# In the vulnerable version, the application was effectively running in a
# debug-like state where unhandled exceptions would return a full traceback.
# This is simulated here by enabling Flask's debug mode.
app = Flask(__name__)
app.config['DEBUG'] = True

# The route is accessible without any authentication checks.
# It takes a path-like variable from the URL.
@app.route('/web/<path:filename>')
def serve_template(filename):
    """
    This function attempts to render a template using the filename
    provided by the user in the URL.
    """
    try:
        # If an attacker requests a template that does not exist,
        # e.g., /web/nonexistent.html, this line will raise
        # a TemplateNotFound exception.
        return render_template(filename)
    except TemplateNotFound:
        # In a properly configured app, this would be caught and a
        # generic 404 page would be returned. In the vulnerable code,
        # the exception was not handled, allowing the framework's debug
        # handler to expose the stack trace. To simulate this, we re-raise
        # the exception so the debug handler catches it.
        raise

# To run this example:
# 1. Save it as `vulnerable_app.py`.
# 2. Make sure you have Flask installed (`pip install Flask`).
# 3. Create an empty directory named `templates` in the same folder.
# 4. Run the script: `python vulnerable_app.py`.
# 5. Open your browser and navigate to `http://127.0.0.1:5000/web/does-not-exist.html`.
# You will see a detailed Flask debug page with the full traceback.
if __name__ == '__main__':
    # Note: Running with app.run() directly is not for production.
    # The vulnerability was in how the pyLoad application was packaged and run,
    # exposing these debug tracebacks.
    app.run(host='0.0.0.0', port=5000)

Patched code sample

import logging
from flask import Flask, render_template, Response

# This example uses the Flask web framework to demonstrate the principle of the fix.
# The vulnerability involved a web server returning detailed Python tracebacks
# to the user upon an unhandled exception. The fix is to catch such
# exceptions at a high level and return a generic error message instead.

app = Flask(__name__)

# This simulates the vulnerable endpoint. A request for a template that does not
# exist will raise an exception. This endpoint is reachable without authentication.
@app.route("/web/<path:filename>")
def get_resource(filename):
    # This line will raise a jinja2.exceptions.TemplateNotFound exception
    # if the template file does not exist in the 'templates' folder.
    return render_template(filename)


# --- THE FIX ---
# A generic exception handler is registered for the application.
# This handler catches any unhandled exception (like the TemplateNotFound error
# from the route above) and prevents the web server's default debug traceback
# from being sent to the client.
@app.errorhandler(Exception)
def handle_unhandled_exception(e):
    # 1. Log the full exception for server-side debugging (optional but good practice).
    #    This ensures developers can still see what went wrong.
    app.logger.error(f"Unhandled exception on endpoint: {e}", exc_info=True)

    # 2. Return a generic 500 error response to the client. This hides internal
    #    implementation details, file paths, and stack traces.
    return Response("Internal Server Error", status=500, mimetype='text/plain')

Cite this entry

@misc{vaitp:cve202644226,
  title        = {{pyLoad WebUI leaks Python stack traces to unauthenticated users.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-44226},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-44226/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::