VYPR
Critical severity9.8NVD Advisory· Published Jul 15, 2025· Updated Apr 15, 2026

CVE-2025-53890

CVE-2025-53890

Description

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.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
pyload-ngPyPI
< 0.200.20

Patches

1
909e5c978852

Fix Improper Neutralization of Input code injection interactive.user (#4586)

https://github.com/pyload/pyloadZeroday BYTEJul 11, 2025via ghsa
1 file changed · +94 92
  • src/pyload/webui/app/static/js/captcha-interactive.user.js+94 92 modified
    @@ -1,7 +1,7 @@
     // ==UserScript==
     // @name         pyLoad Script for Interactive Captcha
     // @namespace    https://pyload.net/
    -// @version      0.19
    +// @version      0.20
     // @author       Michi-F, GammaC0de
     // @description  pyLoad Script for Interactive Captcha
     // @homepage     https://github.com/pyload/pyload
    @@ -35,97 +35,99 @@
     */
     
     (function() {
    -    'use strict';
    +  'use strict';
     
    -    // this function listens to messages from the pyload main page
    -    window.addEventListener('message', function(e) {
    -        try {
    -            var request = JSON.parse(e.data);
    -        } catch(e) {
    -            return
    -        }
    -        if(request.constructor === {}.constructor && request.actionCode === "pyloadActivateInteractive") {
    -            if (request.params.script) {
    -                var sig = new KJUR.crypto.Signature({"alg": "SHA384withRSA", "prov": 'cryptojs/jsrsa'});
    -                sig.init("-----BEGIN PUBLIC KEY-----\n" +
    -                    "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuEHE4uAeTeEQjIwB//YH\n" +
    -                    "Gl5e058aJRCRyOvApv1iC1ZQgXGHopgEd528+AtkAZKdCRkoNCWda7L/hROpZNjq\n" +
    -                    "xgO5NjjlBnotntQiZ6xr7A4Kfdctmw1DPcv/dkp6SXRpAAw8BE9CctZ3H7cE/4UT\n" +
    -                    "FIJOYQQXF2dcBTWLnUAjesNoHBz0uHTdvBIwJdfdUIrNMI4IYXL4mq9bpKNvrwrb\n" +
    -                    "iNhSqN0yV8sanofZmDX4JUmVGpWIkpX0u+LA4bJlaylwPxjuWyIn5OBED0cdqpbO\n" +
    -                    "7t7Qtl5Yu639DF1eZDR054d9OB3iKZX1a6DTg4C5DWMIcU9TsLDm/JJKGLWRxcJJ\n" +
    -                    "fwIDAQAB\n" +
    -                    "-----END PUBLIC KEY----- ");
    -                sig.updateString(request.params.script.code);
    -                if (sig.verify(request.params.script.signature)) {
    -                    window.gpyload = {
    -                        isVisible : function(element) {
    -                            var style = window.getComputedStyle(element);
    -                            return !(style.width === 0 ||
    -                                    style.height === 0 ||
    -                                    style.opacity === 0 ||
    -                                    style.display ==='none' ||
    -                                    style.visibility === 'hidden'
    -                            );
    -                        },
    -                        debounce : function (fn, delay) {
    -                          var timer = null;
    -                          return function () {
    -                            var context = this, args = arguments;
    -                            clearTimeout(timer);
    -                            timer = setTimeout(function () {
    -                                fn.apply(context, args);
    -                            }, delay);
    -                          };
    -                        },
    -                        submitResponse: function(response) {
    -                            if (typeof gpyload.observer !== 'undefined') {
    -                                gpyload.observer.disconnect();
    -                            }
    -                            var responseMessage = {actionCode: "pyloadSubmitResponse", params: {response: response}};
    -                            parent.postMessage(JSON.stringify(responseMessage),"*");
    -                        },
    -                        activated: function() {
    -                            var responseMessage = {actionCode: "pyloadActivatedInteractive"};
    -                            parent.postMessage(JSON.stringify(responseMessage),"*");
    -                        },
    -                        setSize : function(rect) {
    -                            if (gpyload.data.rectDoc.left !== rect.left || gpyload.data.rectDoc.right !== rect.right || gpyload.data.rectDoc.top !== rect.top || gpyload.data.rectDoc.bottom !== rect.bottom) {
    -                                gpyload.data.rectDoc = rect;
    -                                var responseMessage = {actionCode: "pyloadIframeSize", params: {rect: rect}};
    -                                parent.postMessage(JSON.stringify(responseMessage), "*");
    -                            }
    -                        },
    -                        data : {
    -                            debounceInterval: 1500,
    -                            rectDoc: {top: 0, right: 0, bottom: 0, left: 0}
    -                        }
    -                    };
    -
    -                    try {
    -                        eval(request.params.script.code);
    -                    } catch(err) {
    -                        console.error("pyLoad: Script aborted: " + err.name + ": " + err.message + " (" + err.stack +")");
    -                        return;
    -                    }
    -                    if (typeof gpyload.getFrameSize === "function") {
    -                        var checkDocSize = gpyload.debounce(function() {
    -                            window.scrollTo(0,0);
    -                            var rect = gpyload.getFrameSize();
    -                            gpyload.setSize(rect);
    -                        }, gpyload.data.debounceInterval);
    -                        gpyload.observer = new MutationObserver(function(mutationsList) {
    -                            checkDocSize();
    -                        });
    -                        var js_script = document.createElement("script");
    -                        js_script.type = "text/javascript";
    -                        js_script.innerHTML = "gpyload.observer.observe(document.querySelector('body'), {attributes:true, attributeOldValue:false, characterData:true, characterDataOldValue:false, childList:true, subtree:true});";
    -                        document.getElementsByTagName('body')[0].appendChild(js_script);
    -                    }
    -                } else {
    -                    console.error("pyLoad: Script signature verification failed")
    -                }
    +  // this function listens to messages from the pyload main page
    +  window.addEventListener('message', function(e) {
    +    let request;
    +    try {
    +      request = JSON.parse(e.data);
    +    } catch(e) {
    +      return
    +    }
    +    if(request.constructor === {}.constructor && request.actionCode === "pyloadActivateInteractive") {
    +      if (request.params.script) {
    +        const sig = new KJUR.crypto.Signature({"alg": "SHA384withRSA", "prov": 'cryptojs/jsrsa'});
    +        sig.init("-----BEGIN PUBLIC KEY-----\n" +
    +          "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuEHE4uAeTeEQjIwB//YH\n" +
    +          "Gl5e058aJRCRyOvApv1iC1ZQgXGHopgEd528+AtkAZKdCRkoNCWda7L/hROpZNjq\n" +
    +          "xgO5NjjlBnotntQiZ6xr7A4Kfdctmw1DPcv/dkp6SXRpAAw8BE9CctZ3H7cE/4UT\n" +
    +          "FIJOYQQXF2dcBTWLnUAjesNoHBz0uHTdvBIwJdfdUIrNMI4IYXL4mq9bpKNvrwrb\n" +
    +          "iNhSqN0yV8sanofZmDX4JUmVGpWIkpX0u+LA4bJlaylwPxjuWyIn5OBED0cdqpbO\n" +
    +          "7t7Qtl5Yu639DF1eZDR054d9OB3iKZX1a6DTg4C5DWMIcU9TsLDm/JJKGLWRxcJJ\n" +
    +          "fwIDAQAB\n" +
    +          "-----END PUBLIC KEY----- ");
    +        sig.updateString(request.params.script.code);
    +        if (sig.verify(request.params.script.signature)) {
    +          window.gpyload = {
    +            isVisible : function(element) {
    +              const style = window.getComputedStyle(element);
    +              return !(style.width === 0 ||
    +                style.height === 0 ||
    +                style.opacity === 0 ||
    +                style.display ==='none' ||
    +                style.visibility === 'hidden'
    +              );
    +            },
    +            debounce : function (fn, delay) {
    +              let timer = null;
    +              return function () {
    +                const context = this, args = arguments;
    +                clearTimeout(timer);
    +                timer = setTimeout(function () {
    +                  fn.apply(context, args);
    +                }, delay);
    +              };
    +            },
    +            submitResponse: function(response) {
    +              if (typeof gpyload.observer !== 'undefined') {
    +                gpyload.observer.disconnect();
    +              }
    +              const responseMessage = {actionCode: "pyloadSubmitResponse", params: {response: response}};
    +              parent.postMessage(JSON.stringify(responseMessage),"*");
    +            },
    +            activated: function() {
    +              const responseMessage = {actionCode: "pyloadActivatedInteractive"};
    +              parent.postMessage(JSON.stringify(responseMessage),"*");
    +            },
    +            setSize : function(rect) {
    +              if (gpyload.data.rectDoc.left !== rect.left || gpyload.data.rectDoc.right !== rect.right || gpyload.data.rectDoc.top !== rect.top || gpyload.data.rectDoc.bottom !== rect.bottom) {
    +                gpyload.data.rectDoc = rect;
    +                const responseMessage = {actionCode: "pyloadIframeSize", params: {rect: rect}};
    +                parent.postMessage(JSON.stringify(responseMessage), "*");
    +              }
    +            },
    +            data : {
    +              debounceInterval: 1500,
    +              rectDoc: {top: 0, right: 0, bottom: 0, left: 0}
                 }
    +          };
    +
    +          try {
    +            let scriptFunction = new Function('request', 'gpyload', '"use strict";' + request.params.script.code);
    +            scriptFunction(request, gpyload);
    +          } catch(err) {
    +            console.error("pyLoad: Script aborted: " + err.name + ": " + err.message + " (" + err.stack +")");
    +            return;
    +          }
    +          if (typeof gpyload.getFrameSize === "function") {
    +            const checkDocSize = gpyload.debounce(() => {
    +              window.scrollTo(0,0);
    +              var rect = gpyload.getFrameSize();
    +              gpyload.setSize(rect);
    +            }, gpyload.data.debounceInterval);
    +            gpyload.observer = new MutationObserver(function(mutationsList) {
    +              checkDocSize();
    +            });
    +            const js_script = document.createElement("script");
    +            js_script.type = "text/javascript";
    +            js_script.innerHTML = "gpyload.observer.observe(document.querySelector('body'), {attributes:true, attributeOldValue:false, characterData:true, characterDataOldValue:false, childList:true, subtree:true});";
    +            document.getElementsByTagName('body')[0].appendChild(js_script);
    +          }
    +        } else {
    +          console.error("pyLoad: Script signature verification failed")
             }
    -    });
    -})();
    \ No newline at end of file
    +      }
    +    }
    +  });
    +})();
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.