DEV Community

DaNeil C
DaNeil C

Posted on

The Evil JavaScript eval()

So you need to handle some user input

The Evil eval()

eval() is a global function in JavaScript that evaluates a string of code and executes it. The eval() function is fast and "invokes the JavaScript compiler. Since JSON is a proper subset of JavaScript, the compiler will correctly parse the text and produce an object structure. The text must be wrapped in parentheses to avoid tripping on an ambiguity in JavaScript’s syntax.

var myObject = eval(‘(‘ + myJSONtext + ‘)’);
” (6)

Below is a simple string of "a + b" and you can see that the eval() function does the math for it and will output "4". It's pretty handy if you need to evaluate some code on the fly.

var a = 2; 
var b = 2;
console.log(eval('a + b'));
// output: 4
Enter fullscreen mode Exit fullscreen mode

Where is eval() used?

Because data received from a web server is always a string the eval() function is commonly used to convert the strings received from a web server into a JSON object.

var str = '({"firstName":"John","lastName":"Smith"})';
var obj = eval(str);
obj.firstName; // John 
Enter fullscreen mode Exit fullscreen mode

What is a JSON object?

In case you don't already know, JavaScript Object Notation (JSON) is a file format, and data interchange format, that uses human-readable text to store and transmit data objects, consisting of key/value pairs and array data types, to make it easier for machines to parse and generate.

Why is the eval() function evil?

The JavaScript eval() function is great because it doesn't differentiate between a JavaScript expression, variable, statement, or sequence of statements.... but this is also why it is evil as it will also execute any code it's passed with the privileges of the sender.

foo = 2;
eval('foo = foo + 2;alert(foo);');
Enter fullscreen mode Exit fullscreen mode

Because the eval() function doesn't care what it's evaluating it becomes dangerous if you use eval() on a string that could be modified by a malicious user. This runs the risk of running malicious code on the user's machine with the permissions of your webpage/extension.
The eval() function is also evil because any third-party code can see the scope in which eval() was invoked, which can lead to possible attacks. (4)

If your website uses the eval() function to display user names from an input box display the name in an alert box or search the database for the user's name, this could be leveraged to display files on the server the malicious user shouldn't have access to.

Say your function that handles usernames might look like:

var str = '({"firstName":"John","lastName":"Smith"})';
var obj = eval(str);
eval('alert("Welcome Back: " + obj.firstName.);');

Output: John
Enter fullscreen mode Exit fullscreen mode

A malicious user could not put in their name but instead puts /etc/passwd, a file or other sensitive files could be displayed instead of their name.

var str = '({"firstName":"fs.readFileSync('cat /etc/passwd')+''","lastName":"Smith"})';
var obj = eval(str);
eval('alert("Welcome Back: " + obj.firstName.);');

Output: tom:x:1000:1000:Vivek Gite:/home/vivek:/bin/bash
Enter fullscreen mode Exit fullscreen mode

Fear not! There is an alternative, json.parse()

Though both eval() and json.parse() can take a JSON string and then transform it into a JavaScript object, json.parse() is safer to use because the eval() function will execute js where json.parse() will only process valid JSON string representations into a JavaScript value or JSON object. json.parse() will throw an error if invalid JSON strings are passed to it.

const myPets = {
  dog: 0,
  cat: 2,
  koala: "I wish",
  total: 2
};

console.log(JSON.stringify(myPets));
// result: {"dog":0,"cat":2,"koala":"I wish","count":2}

console.log(JSON.parse(JSON.stringify(myPets)));
// result: Object {dog: 0, cat: 2, koala: "I wish", count: 2}
Enter fullscreen mode Exit fullscreen mode

Stay Safe

Remember, the use of JSON.parse() is the best choice if the data being processed is coming from an untrusted source, but it is not the only thing that needs to be done to protect against untrusted data. Don't forget to use safe parameterized interfaces with strong typing and to always validate/sanitize and encode untrusted input.


Happy Hacking

Resources:

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
  2. https://en.wikipedia.org/wiki/JSON
  3. https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON
  4. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
  5. https://www.geeksforgeeks.org/converting-json-text-to-javascript-object/
  6. http://www.json.org/js.html
Please Note: that I am still learning and if something that I have stated is incorrect please let me know. I would love to learn more about what I may not understand fully.

Latest comments (0)