VAITP Dataset

← Back to the dataset

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.

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_command

Patched 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 ::