CVE-2025-53890
pyLoad CAPTCHA processing allows unauthenticated remote code execution.
- CVSS 9.8
- CWE-94
- Input Validation and Sanitization
- Remote
pyload is an open-source Download Manager written in pure Python. An unsafe JavaScript evaluation vulnerability in pyLoad’s CAPTCHA processing code allows unauthenticated remote attackers to execute arbitrary code in the client browser and potentially the backend server. Exploitation requires no user interaction or authentication and can result in session hijacking, credential theft, and full system remote code execution. Commit 909e5c97885237530d1264cfceb5555870eb9546, the patch for the issue, is included in version 0.5.0b3.dev89.
- CWE
- CWE-94
- CVSS base score
- 9.8
- Published
- 2025-07-15
- 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 pyload to version 0.5.0b3.dev89 or later.
Vulnerable code sample
def process_captcha_result(captcha_solution_from_service):
"""
This function represents the vulnerable logic in pyLoad's CAPTCHA
processing code before it was fixed.
It takes a string result from a CAPTCHA service and constructs a
JavaScript command string from it. This command string was intended
to be sent to the user's web browser and executed.
"""
# VULNERABLE LINE:
# The `captcha_solution_from_service` string is unsafely embedded
# into a JavaScript command using basic string formatting.
# If an attacker could control the string returned by the CAPTCHA service
# (e.g., by providing a malicious service or through a Man-in-the-Middle attack),
# they could inject arbitrary JavaScript code.
#
# For example, a malicious `captcha_solution_from_service` string like:
# ");alert('XSS');pyload.captcha.setResult("foo
#
# Would result in the following JavaScript payload being created:
# pyload.captcha.setResult("");alert('XSS');pyload.captcha.setResult("foo")
#
# When this payload is executed by the client (which used `eval()`), the
# attacker's `alert('XSS')` script would run in the user's browser.
js_command = 'pyload.captcha.setResult("%s")' % captcha_solution_from_service
return js_commandPatched code sample
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import json
import re
from ..jdownloader.jd_unpacker import JdUnpacker
from ..utils import _
__all__ = ['JsUnpacker']
class JsUnpacker(JdUnpacker):
__name__ = "JsUnpacker"
__type__ = "hook"
__version__ = "0.20"
__status__ = "testing"
__description__ = """Unpacker for javascript packed code""":
__license__ = "GPLv3"
__authors__ = [("Walter Purcaro", "vuolter@gmail.com")]
def unpack(self, javascript):
"""
Unpacks javascript code
"""
self.log_debug(_("Unpacking javascript"))
try:
res = self.eval(javascript)
except Exception as e:
self.log_warning(_("Javascript execution failed"), e)
res = ""
return res
def eval(self, javascript):
"""Secure function that fixes the vulnerability."""
# a little bit of regex to extract the payload
payload = re.search(r"eval\(function\(p,a,c,k,e,d\)(.|\n)*?\)\)", javascript)
if not payload:
return
payload = payload.group(0)
# a little bit of regex to extract the function arguments
args = re.search(r"function\((.*?)\)", payload)
if not args:
return
args = args.group(1).split(',')
# a little bit of regex to extract the function body
body = re.search(r"\{(.*)\}", payload, re.DOTALL)
if not body:
return
body = body.group(1)
# a little bit of regex to extract the function call arguments
call_args = re.search(r"\}\((.*?)\)", payload, re.DOTALL)
if not call_args:
return
call_args = json.loads("[" + call_args.group(1).replace("'", '"') + "]")
# create a new function with the extracted arguments and body
# this is safe because we are not evaluating any code
# we are just creating a new function
function = self.create_function(args, body)
# call the new function with the extracted call arguments
return function(*call_args)Payload
alert(document.cookie)
Cite this entry
@misc{vaitp:cve202553890,
title = {{pyLoad CAPTCHA processing allows unauthenticated remote code execution.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2025},
note = {VAITP Python Vulnerability Dataset, entry CVE-2025-53890},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-53890/}}
}
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 ::
