252

How do I execute some JavaScript that is a string?

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    // how do I get a browser to alert('hello')?
}
bluish
  • 26,356
  • 27
  • 122
  • 180
divinci
  • 22,329
  • 11
  • 45
  • 56

22 Answers22

321

With the eval function, like:

eval("my script here");

WARNING: Any malicious code contained within the string will be executed with the same privileges of your site, make absolutely sure you can trust the source.

Zach Jensz
  • 3,650
  • 5
  • 15
  • 30
Lennart Koopmann
  • 20,313
  • 4
  • 26
  • 33
  • 27
    Be carefull ! This gonna execute the code therefore be careful of where/how you got this string. Mind that anyone may try to insert malicious code inside your string. – Jon Aug 08 '18 at 09:27
  • 2
    @divinci This is called "Cross Site Scripting". See here: https://en.wikipedia.org/wiki/Cross-site_scripting. – Brendon Shaw Nov 18 '18 at 21:10
180

You can execute it using a function. Example:

var theInstructions = "alert('Hello World'); var x = 100";

var F=new Function (theInstructions);

return(F());
stefan
  • 1,809
  • 1
  • 11
  • 2
  • 3
    but in the end - isn't that the same as calling `var F=function(){eval(theInstructions);};`? – Jörn Berkefeld Feb 12 '14 at 18:08
  • 20
    yes and no: with eval code would be also executed, while with Function() code isn't executed until F() (use case? check for syntax error but don't want to execute the code) – G3z Jan 03 '15 at 01:02
  • 4
    @stefan It's beatifull... `new Function("alert('Hello World');")()` – Andrés Morales Apr 11 '16 at 21:32
  • 2
    I tried this inside a try/catch block, and it works perfectly. I can now take any JavaScript code typed into a text block, pass it to my function, and execute it. The catch block can then insert error messages from the JavaScript engine into a DOM element and display any errors in the code. If someone wants the function I wrote, then once I've tidied it up, I can post it here. – David Edwards Dec 01 '18 at 20:50
  • @DavidEdwards Would be awesome if you still have it and post it. – Anoop May 16 '19 at 03:47
  • Would this be faster than using eval() - not considering the part where eval is dangerous, forgetting that now. Is it faster? Or it's all the same because the code is in a string and it gets slow too? (Is the problem of slowness of eval() being in the code being in a string?) – Edw590 Apr 15 '20 at 14:54
  • wrote it into a one liner `return(new Function ("alert('Hello World'); var x = 100")); ` no idea if this works, i would reccoment just using `eval` – Bluppie05 Nov 03 '20 at 00:29
  • One liner should be `return(new Function ("alert('Hello World'); var x = 100")());` – Andrey Ptashinskiy Oct 20 '21 at 09:00
  • See an extension of this answer here: https://stackoverflow.com/a/66484305/7880517 – Sebastian Norr Feb 07 '22 at 23:22
  • variable in the `new Function` will become local scoped variable – xgqfrms Apr 14 '22 at 15:40
  • This also has the advantage you can bind an object to the function (using the "bind" method) so you can pass parameters to the statement being evaluated. – Michael Erickson Aug 29 '23 at 02:49
71

The eval function will evaluate a string that is passed to it.

But the use of eval is super dangerous AND slow, so use with caution.

coobird
  • 159,216
  • 35
  • 211
  • 226
  • 49
    super dangerous AND slow - you should bold, italic, underline, and h1 that – annakata Jun 02 '09 at 13:00
  • 5
    I'm doubtful that it's any slower than loading JavaScript anywhere else on the page, that has to be parsed as well. If it's slower, it it's because it's done in a different scope, which might force to creation of resources for that scope. – cgp Jun 02 '09 at 13:16
  • 9
    If you say `eval()` is dangerous. Is there any alternative? – white_gecko May 22 '12 at 15:36
  • 1
    @white_gecko It depends on what needs to be accomplished. The "eval can be dangerous" link has a few concrete cases where an alternative to `eval` is available. One thing that is certain is that running `eval` on a user-provided string is a serious security issue. – coobird May 22 '12 at 15:43
  • 7
    @coobird I know this is a little late but why is that dangerous? The user can easily run JavaScript code on your website using the console. – jkd Mar 23 '15 at 23:22
  • 1
    @jakeimds it can be dangerous if that javascript string is passed to a different user's browser and evaluated there – Moishe Lipsker May 21 '15 at 19:11
  • 14
    if your security depends at all on client-side javascript, you've screwed up big time and it has nothing to do with eval. – Matthew Aug 13 '15 at 14:25
  • For the people who are wondering why this is dangerous. If we are allowing eval() on user content say a comment field on your blog site. somebody can write javascript there to steal cookies of other users who are visiting the same page, or redirect users to a malacious site. For more info read about cross site scripting. – Ryu_hayabusa Sep 18 '15 at 08:49
  • 2
    The dangerous part is not a user executing code on **their** machine. It is a user executing someone else's code. – Nelson Apr 03 '19 at 08:40
33

For users that are using node and that are concerned with the context implications of eval() nodejs offers vm. It creates a V8 virtual machine that can sandbox the execution of your code in a separate context.

Taking things a step further is vm2 which hardens vm allowing the vm to run untrusted code.

const vm = require('vm');

const x = 1;

const sandbox = { x: 2 };
vm.createContext(sandbox); // Contextify the sandbox.

const code = 'x += 40; var y = 17;';
// `x` and `y` are global variables in the sandboxed environment.
// Initially, x has the value 2 because that is the value of sandbox.x.
vm.runInContext(code, sandbox);

console.log(sandbox.x); // 42
console.log(sandbox.y); // 17

console.log(x); // 1; y is not defined.
Eric Kigathi
  • 1,815
  • 21
  • 23
22

Try this:

  var script = "<script type='text/javascript'> content </script>";
  //using jquery next
  $('body').append(script);//incorporates and executes inmediatelly

Personally, I didn't test it but seems to work.

yanko
  • 164
  • 9
21

Use eval().

W3 Schools tour of eval. Site has some usable examples of eval. The Mozilla documentation covers this in detail.

You will probably get a lot of warnings about using this safely. do NOT allow users to inject ANYTHING into eval() as it is a huge security issue.

You'll also want to know that eval() has a different scope.

cgp
  • 41,026
  • 12
  • 101
  • 131
  • 11
    http://www.w3fools.com/. The W3C doesn't even have anything to say about eval. If you want to link to something official, target http://ecma-international.org/ecma-262/5.1/#sec-15.1.2.1 – Bergi Aug 05 '13 at 15:34
  • 8
    I didn't want to "link to anything official, I wanted to link to something readable - Looking at what *you* linked, it gives no explanation of how it is used, no examples, no way to tinker, and describes the method in isolation. For a beginner, it is a completely inappropriate link. Hey, you wouldn't happen to be @bjorninge, would you? – cgp Aug 14 '13 at 21:56
  • 1
    The spec describes `eval` better to me than that W3Schools article. Something readable with good explanation and examples would be https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval. And no, I'm not bjorninge – Bergi Aug 15 '13 at 09:36
  • I will agree that it's not documentation, and I will agree that mozilla's page is a better overall picture of it. Slightly tweaked my answer based on feedback – cgp Aug 15 '13 at 17:14
  • 1
    Regarding that ecma-international.org link, I would describe it as readable and appreciable by everyone with more than 15 minutes experience with JS. It's very nice. – i336_ Jan 02 '17 at 11:26
19
new Function('alert("Hello")')();

I think this is the best way.

MyMeMo
  • 189
  • 1
  • 5
17

A bit like what @Hossein Hajizadeh alerady said, though in more detail:

There is an alternative to eval().

The function setTimeout() is designed to execute something after an interval of milliseconds, and the code to be executed just so happens to be formatted as a string.

It would work like this:

ExecuteJavascriptString(); //Just for running it

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    setTimeout(s, 1);
}

1 means it will wait 1 millisecond before executing the string.

It might not be the most correct way to do it, but it works.

atjn
  • 467
  • 5
  • 15
  • 3
    Why waste one millisecond when you can pass 0 (zero) to `setTimeout`? Note that in any case it will make the execution asynchronous. It means that all code that follows the `setTimeout` call will be invoked _before_ the code passed to `setTimeout` (even if called with 0 (zero)). – jox May 16 '20 at 22:06
  • ‍♀️ just thought it better explained how setTimeout works – atjn Jun 11 '20 at 09:30
9

Checked this on many complex and obfuscated scripts:

var js = "alert('Hello, World!');" // put your JS code here
var oScript = document.createElement("script");
var oScriptText = document.createTextNode(js);
oScript.appendChild(oScriptText);
document.body.appendChild(oScript);
rlib
  • 7,444
  • 3
  • 32
  • 40
7

New Function and apply() together works also

var a=new Function('alert(1);')
a.apply(null)
Reiner
  • 1,621
  • 1
  • 16
  • 22
  • This is better than `eval()`. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function – sziraqui May 11 '20 at 06:58
  • can you use `apply` without the varialbe? The following fails: `("new Function('alert(1);')").apply` – johny why Nov 15 '22 at 15:31
  • 1
    @johnywhy You need the parameter, it's mandatory as scope https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply – Reiner Nov 17 '22 at 19:44
7

Use eval as below. Eval should be used with caution, a simple search about "eval is evil" should throw some pointers.

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    eval(s);
}
xk0der
  • 3,660
  • 4
  • 26
  • 35
6

If you want to execute a specific command (that is string) after a specific time - cmd=your code - InterVal=delay to run

 function ExecStr(cmd, InterVal) {
    try {
        setTimeout(function () {
            var F = new Function(cmd);
            return (F());
        }, InterVal);
    } catch (e) { }
}
//sample
ExecStr("alert(20)",500);
Hossein Hajizadeh
  • 1,357
  • 19
  • 10
5

I was answering similar question and got yet another idea how to achieve this without use of eval():

const source = "alert('test')";
const el = document.createElement("script");
el.src = URL.createObjectURL(new Blob([source], { type: 'text/javascript' }));
document.head.appendChild(el);

In the code above you basically create Blob, containing your script, in order to create Object URL (representation of File or Blob object in browser memory). Since you have src property on <script> tag, the script will be executed the same way as if it was loaded from any other URL.

akrn
  • 748
  • 5
  • 7
4
function executeScript(source) {
    var script = document.createElement("script");
    script.onload = script.onerror = function(){ this.remove(); };
    script.src = "data:text/plain;base64," + btoa(source);
    document.body.appendChild(script);
}

executeScript("alert('Hello, World!');");
Oleg
  • 486
  • 6
  • 12
4

An extention of Stefan's answer:

//Executes immediately
function stringToFunctionAndExecute(str) {
    let func = new Function(str);
    return (func()); // <--- note the parenteces
}

//Executes when called
function stringToFunctionOnly(str) {
    let func = new Function(str);
    return func;
}

// -^-^-^- Functions -^-^-^- (feel free to copy)
// -v-v-v- Explanations -v-v-v- (run code to read easier)

console.log('STEP 1, this executes directly when run:')
let func_A = stringToFunctionAndExecute("console.log('>>> executes immediately <<<')");

console.log("STEP 2, and you can't save it in a variable, calling a() will throw an error, watch:")
try {
  func_A();    
} catch (error) {
  console.log('STEP ERROR, see, it failed', error)    
}

console.log('STEP 3, but this will NOT execute directly AND you can save it for later...')
let func_B = stringToFunctionOnly("console.log('>>> executes when called <<<')");

console.log("STEP 4, ...as you see, it only run when it's called for, as is done now:")
func_B();

console.log('STEP 5, TADAAAAA!!')
Sebastian Norr
  • 7,686
  • 2
  • 12
  • 17
4
eval(s);

But this can be dangerous if you are taking data from users, although I suppose if they crash their own browser thats their problem.

UnkwnTech
  • 88,102
  • 65
  • 184
  • 229
  • 1
    exactly. Eval is dangerous on the server side. On the client... not so much. The user could just type in javascript:someevilcode in to the address of the browser and boom. Eval right there. – Esben Skov Pedersen Jan 29 '10 at 09:28
  • @EsbenSkovPedersen That's prevented in chrome at least, and it requires user action, as opposed to a site that `eval`s code from users, which could for instance let users steal other user's accounts without them knowing just by loading the page. – 1j01 May 27 '15 at 01:35
  • 1
    @1j01 To be fair my comment is five years old. – Esben Skov Pedersen May 27 '15 at 07:25
  • @EsbenSkovPedersen That's true :) – 1j01 May 27 '15 at 13:13
3

Not sure if this is cheating or not:

window.say = function(a) { alert(a); };

var a = "say('hello')";

var p = /^([^(]*)\('([^']*)'\).*$/;                 // ["say('hello')","say","hello"]

var fn = window[p.exec(a)[1]];                      // get function reference by name

if( typeof(fn) === "function") 
    fn.apply(null, [p.exec(a)[2]]);                 // call it with params
Zachary Scott
  • 20,968
  • 35
  • 123
  • 205
2

One can use mathjs

Snippet from above link:

// evaluate expressions
math.evaluate('sqrt(3^2 + 4^2)')        // 5
math.evaluate('sqrt(-4)')               // 2i
math.evaluate('2 inch to cm')           // 5.08 cm
math.evaluate('cos(45 deg)')            // 0.7071067811865476

// provide a scope
let scope = {
    a: 3,
    b: 4
}
math.evaluate('a * b', scope)           // 12
math.evaluate('c = 2.3 + 4.5', scope)   // 6.8
scope.c                                

scope is any object. So if you pass the global scope to the evalute function, you may be able to execute alert() dynamically.

Also mathjs is much better option than eval() because it runs in a sandbox.

A user could try to inject malicious JavaScript code via the expression parser. The expression parser of mathjs offers a sandboxed environment to execute expressions which should make this impossible. It’s possible though that there are unknown security vulnerabilities, so it’s important to be careful, especially when allowing server side execution of arbitrary expressions.

Newer versions of mathjs does not use eval() or Function().

The parser actively prevents access to JavaScripts internal eval and new Function which are the main cause of security attacks. Mathjs versions 4 and newer does not use JavaScript’s eval under the hood. Version 3 and older did use eval for the compile step. This is not directly a security issue but results in a larger possible attack surface.

sziraqui
  • 5,763
  • 3
  • 28
  • 37
2

eval should do it.

eval(s);
Vincent Ramdhanie
  • 102,349
  • 23
  • 137
  • 192
1

Using both eval and creating a new Function to execute javascript comes with a lot of security risks.

const script = document.createElement("script");
const stringJquery = '$("#button").on("click", function() {console.log("hit")})';
script.text = stringJquery;
document.body.appendChild(script);

I prefer this method to execute the Javascript I receive as a string.

MapMyMind
  • 113
  • 10
1

This method avoids use of potentially-risky eval, provides callable functions, uses strict mode on the expression evaluator for extra reliability, and less verbose than other answers.

execute a string command

function string_cmd(sCmd) {
    new Function(sCmd)();
}

evaluate a string expression

function string_exp(sCmd) {
    return Function(
        `'use strict'; 
        return (${sCmd})`
        )();
}

usage:

const result = string_exp("2+2");

string_cmd("alert(result)");

https://codepen.io/johnaweiss/pen/mdKpyZL

johny why
  • 2,047
  • 7
  • 27
  • 52
1
eval(s);

Remember though, that eval is very powerful and quite unsafe. You better be confident that the script you are executing is safe and unmutable by users.

PatrikAkerstrand
  • 45,315
  • 11
  • 79
  • 94
  • 1
    In JS everything can be changed by the user just type "javascript:document.write("Hello World");" into almost any browser's address bar. – UnkwnTech Jun 02 '09 at 12:58
  • 1
    Yes, but you can make it harder for him by not using global variables, hiding your functions in closures etc. Also, by avoiding eval like the plague =) – PatrikAkerstrand Jun 02 '09 at 13:05