Подтвердить что ты не робот

Проблема безопасности строк шаблона ES2015

Здесь цитата из MDN:

Строки шаблонов НЕ ДОЛЖНЫ быть построены ненадежными пользователями, поскольку они имеют доступ к переменным и функциям.

И пример:

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

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

В этом примере не обнаружены уязвимости, которые я вижу.

Может ли кто-нибудь привести пример эксплойта, который использует это?

4b9b3361

Ответ 1

Это не имеет смысла. Строка шаблона не имеет доступа ни к чему, она также не выполняется. Строка шаблона является синтаксическим элементом языка.

Динамическое построение строки шаблона без проблем - это похоже на создание выражения (в любом формате, будь то строка кода или AST). Проблема MDN заключается в оценке такого выражения (например, с использованием eval, сериализации его в script, который подается пользователю и т.д.) - он может содержать произвольный код, в отличие от строкового литерала! Но, конечно же, вы бы этого не сделали, не так ли?

Это предупреждение похоже на то, что "Конкатенации с использованием оператора + не должны создаваться ненадежными пользователями, поскольку они имеют доступ к переменным и функциям". и приведя для него пример "" + console.warn("this is",this) + "". Ну, это верно для любого выражения языка, поэтому это не особенно интересно.


В то время как мы говорим о дрянной кодировке, есть, конечно, сценарий, в котором использование строк шаблонов (эй, они многострочные и еще ничего) вместо строковых литералов может привести к проблемам:

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)+'`;';
//                       ^                                   ^

Теперь представьте, что userInput содержит ${…} - который мы не убежали...

Ответ 2

Я думаю, что @Bergi прав - опасность здесь включает использование eval или подобных методов, позволяющих пользователю создавать фактическую строку шаблона, а не замены.

Пример использования: ленивый разработчик хочет разрешить пользователям выполнять некоторые строковые подстановки в своих комментариях, например. ссылаться на других пользователей или вопросы на сайте типа SO. Вместо того, чтобы разрабатывать токены для этого, а затем делать соответствующий синтаксический анализ и замену, он решает, что он примет синтаксис следующим образом:

"I think ${firstPoster} is an idiot! See ${question(1234)} for details!"

и запустить его с помощью следующей функции:

var firstPoster = {...};
function question() {...}

processInput(input) {
  return eval('`' + input + '`');
}

Если этот код eval 'd на клиенте и показан другим пользователям, злоумышленник может вставить атаку XSS. Если он eval 'd на сервере, злоумышленник может взять под свой контроль машину.