Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES2015 template strings security issue

Here's a quote from MDN:

Template strings MUST NOT be constructed by untrusted users, because they have access to variables and functions.

And an example:

`${console.warn("this is",this)}`; // "this is" Window

let a = 10;
console.warn(`${a+=20}`); // "30"
console.warn(a); // 30

The example here doesn't show any vulnerabilities I can see.

Can anyone give an example of an exploit that takes advantage of this?

like image 518
Mosho Avatar asked Jan 21 '16 22:01

Mosho


People also ask

What are template strings?

Template literals are literals delimited with backtick ( ` ) characters, allowing for multi-line strings, string interpolation with embedded expressions, and special constructs called tagged templates.

What are ES6 template strings?

Template literals are a new feature introduced in ECMAScript 2015/ ES6. It provides an easy way to create multiline strings and perform string interpolation. Template literals are the string literals and allow embedded expressions. Before ES6, template literals were called as template strings.

What is `` in JS?

Backticks ( ` ) are used to define template literals. Template literals are a new feature in ECMAScript 6 to make working with strings easier. Features: we can interpolate any kind of expression in the template literals. They can be multi-line.

Why would you need to use a template literal in JavaScript?

Template literals provide an easy way to interpolate variables and expressions into strings. The method is called string interpolation.


1 Answers

This makes no sense. A template string doesn't have access to anything, it is not executed either. A template string is a syntactical element of the language.

Dynamically constructing a template string is no problem therefore - it's like building an expression (in whatever format, be it a code string or an AST). The problem MDN hints at is with evaluating such an expression (e.g. using eval, serialising it into a script that is served to the user, etc.) - it may contain arbitrary code, in contrast to a string literal! But of course you wouldn't do that anyway, would you?

This warning is like saying "Concatenations using the + operator must not be constructed by untrusted users, because they have access to variables and functions." and giving the example "" + console.warn("this is",this) + "" for it. Well, this is true for any expression of the language, so it's not particularly interesting.


While we are talking about crappy coding, there is of course a scenario where using template strings (hey, they're multiline and whatnot) instead of string literals can lead to problems:

function escapeString(str) {
    return JSON.stringify(str).slice(1, -1)
           .replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
}

// This is (kinda) fine!
var statement = 'var x = "Hello,\\n'+escapeString(userInput)+'";';
eval(statement); // some kind of evaluation

// But this is not:
var statement = 'var x = `Hello,\n'+escapeString(userInput)+'`;';
//                       ^                                   ^

Now imagine userInput contains a ${…} - which we did not escape…

like image 164
Bergi Avatar answered Oct 08 '22 17:10

Bergi