1

I have a string that looks something like this:

var codeStr = "function a(){alert(4);}"

and I want to turn that into a function.

I can do this using eval or new Function, for example:

var fn = eval(codeStr);

But when the content-security-policy is active and does not allow "unsafe-eval", this is blocked.

Important note: it's not enough to just run the code string. I need to get the return value into a variable too.

The security of running code from string has been taken into consideration.

ColBeseder
  • 3,579
  • 3
  • 28
  • 45

1 Answers1

1

One solution is to add a <script> tag to the page and put the code string inside it, causing it to run. But you want the return value too.

To get the return value, you can wrap the code in a callback function. The really interesting part (well, it surprised me), is that the code runs completely synchronously!

function myEval(codeStr) {
    var result;

    // Define callback
    window.evalCallback = function(r){
        result = r;
    };

    var newScript = document.createElement("script");
    newScript.innerHTML = "evalCallback(" + codeStr + ");";
    /*
     * // Add CSP nonce if relevant
     * newScript.setAttribute("nonce", nonce);
    */
    document.body.appendChild(newScript);

    // Now clean up DOM and global scope
    document.body.removeChild(newScript);
    delete window.evalCallback;

    return result;
};

Then call:

var fn = myEval(codeStr);

This answer is not perfect for all applications as it requires content-security-policy to allow "unsafe-inline" or a "nonce".

ColBeseder
  • 3,579
  • 3
  • 28
  • 45