CVE-2025-61773
pyLoad's web interface is vulnerable to XSS due to insufficient validation.
- CVSS 8.1
- CWE-74
- Input Validation and Sanitization
- Remote
pyLoad is a free and open-source download manager written in Python. In versions prior to 0.5.0b3.dev91, pyLoad web interface contained insufficient input validation in both the Captcha script endpoint and the Click'N'Load (CNL) Blueprint. This flaw allowed untrusted user input to be processed unsafely, which could be exploited by an attacker to inject arbitrary content into the web UI or manipulate request handling. The vulnerability could lead to client-side code execution (XSS) or other unintended behaviors when a malicious payload is submitted. user-supplied parameters from HTTP requests were not adequately validated or sanitized before being passed into the application logic and response generation. This allowed crafted input to alter the expected execution flow. CNL (Click'N'Load) blueprint exposed unsafe handling of untrusted parameters in HTTP requests. The application did not consistently enforce input validation or encoding, making it possible for an attacker to craft malicious requests. Version 0.5.0b3.dev91 contains a patch for the issue.
- CWE
- CWE-74
- CVSS base score
- 8.1
- Published
- 2025-10-09
- OWASP
- A03 Injection
- Orthogonal defect classification
- Checking
- Code defect classification
- Missing Check
- Category
- Input Validation and Sanitization
- Subcategory
- Cross-Site Scripting (XSS)
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Affected component
- pyLoad
- Fixed by upgrading
- Yes
Solution
Upgrade to pyLoad version 0.5.0b3.dev91 or later.
Vulnerable code sample
from flask import Flask, request, Response, make_response
app = Flask(__name__)
# This code is a representative example of the vulnerabilities described
# in CVE-2025-61773 for pyLoad versions prior to 0.5.0b3.dev91.
# It does not originate from the actual pyLoad source code but is created
# to demonstrate the described flaws.
@app.route('/captcha.js')
def captcha_script():
"""
Simulates the vulnerable Captcha script endpoint.
The 'callback' GET parameter is used directly in the JavaScript response
without any sanitization, allowing an attacker to inject arbitrary code.
Exploit Example: /captcha.js?callback=alert(document.cookie)//
"""
# Get the user-supplied callback parameter from the request.
callback_func = request.args.get('callback', 'captchaCallback')
# VULNERABLE LINE: The 'callback_func' parameter is directly embedded into the
# response body. This allows an attacker to break out of the function call
# and execute arbitrary JavaScript.
js_content = f"{callback_func}({{'status': 'ok', 'captcha_id': '12345'}});"
# Create and return a JavaScript response.
response = make_response(js_content)
response.headers['Content-Type'] = 'application/javascript'
return response
@app.route('/cnl')
def click_n_load():
"""
Simulates the vulnerable Click'N'Load (CNL) blueprint.
A 'message' parameter from the GET request is reflected directly into the
HTML page without any escaping or validation, leading to a reflected XSS.
Exploit Example: /cnl?message=<script>alert('XSS in CNL')</script>
"""
# Get a user-supplied message from the request arguments.
message = request.args.get('message', 'Ready to process links.')
# VULNERABLE PART: The 'message' variable, containing unsanitized user input,
# is directly injected into the HTML template. An attacker can supply
# malicious HTML or script tags to be executed by the victim's browser.
html_response = f"""
<!DOCTYPE html>
<html>
<head>
<title>pyLoad - Click'N'Load</title>
</head>
<body>
<h1>Click'N'Load Status</h1>
<div>
<p>Status Message: {message}</p>
</div>
</body>
</html>
"""
return Response(html_response, mimetype='text/html')
if __name__ == '__main__':
# This server is for demonstration purposes only.
# It runs on localhost port 8000.
app.run(host='0.0.0.0', port=8000)Patched code sample
# This code provides a representative example of how a vulnerability like
# the one described in the fictional CVE-2025-61773 could be fixed.
# The core issue is insufficient input validation leading to Cross-Site Scripting (XSS).
# The fix is to properly sanitize user-controlled input before it is rendered in HTML.
# We use Python's standard `html.escape()` for this purpose.
import html
from flask import Flask, request, Response
# This Flask app simulates the pyLoad web interface with the vulnerable endpoints.
app = Flask(__name__)
@app.route("/captcha")
def fixed_captcha_script():
"""
This function represents the fixed Captcha script endpoint.
The vulnerability existed because the 'challenge_id' parameter was taken
from the URL and directly embedded into the HTML response without sanitization.
This allowed an attacker to inject malicious scripts.
The fix involves processing the user input with `html.escape()` before
including it in the response. This function converts special HTML characters
(like <, >, &) into their safe entity equivalents (e.g., <, >, &),
preventing the browser from interpreting the input as code.
"""
# Get potentially malicious user input from the request arguments.
challenge_id = request.args.get('challenge_id', 'default_challenge')
# FIX: Sanitize the user-supplied input to prevent XSS.
# Any malicious script tags or HTML attributes will be converted to plain text.
sanitized_challenge_id = html.escape(challenge_id)
# The sanitized input is now safely rendered in the web UI.
response_html = f"""
<html>
<head><title>Captcha</title></head>
<body>
<h1>Captcha Challenge</h1>
<p>Challenge ID: {sanitized_challenge_id}</p>
<!-- If the input was malicious, it is now displayed as harmless text. -->
</body>
</html>
"""
return Response(response_html, mimetype='text/html')
@app.route("/cnl")
def fixed_click_n_load_blueprint():
"""
This function represents the fixed Click'N'Load (CNL) Blueprint.
Similar to the captcha endpoint, the 'package_name' parameter from a CNL
request was unsafely embedded in the UI, allowing for content injection
and potential client-side code execution.
The fix is identical in principle: all user-controlled data that will be
reflected in the HTML response must be properly escaped to neutralize
any potential XSS payloads.
"""
# Get potentially malicious package name from the request arguments.
package_name = request.args.get('package_name', 'Default Package')
# FIX: Sanitize the package name before rendering it.
sanitized_package_name = html.escape(package_name)
# The sanitized package name is now safe to display to the user.
response_html = f"""
<html>
<head><title>Click'N'Load</title></head>
<body>
<h2>Adding package to download queue...</h2>
<p>Package Name: {sanitized_package_name}</p>
</body>
</html>
"""
return Response(response_html, mimetype='text/html')
if __name__ == '__main__':
# To demonstrate the fix:
# 1. Make sure you have Flask installed: `pip install Flask`
# 2. Run this Python script.
# 3. Open a web browser and test the following URLs:
#
# Test URL with a malicious payload for the captcha endpoint:
# http://127.0.0.1:5000/captcha?challenge_id=<script>alert('XSS_ATTEMPT')</script>
#
# Test URL with a malicious payload for the CNL endpoint:
# http://127.0.0.1:5000/cnl?package_name=<img src=x onerror=alert('CNL_XSS_ATTEMPT')>
#
# In both cases, the browser will display the malicious string as plain text
# instead of executing the script, confirming the vulnerability has been fixed.
app.run(port=5000, debug=False)Payload
<img src=x onerror=alert('XSS')>
Cite this entry
@misc{vaitp:cve202561773,
title = {{pyLoad's web interface is vulnerable to XSS due to insufficient validation.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2025},
note = {VAITP Python Vulnerability Dataset, entry CVE-2025-61773},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-61773/}}
}
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 ::
