#javascript #security #xss #eval
#javascript #Безопасность #xss #eval
Вопрос:
Я создавал (не сейчас, но все еще мне это интересно) игру, использующую HTML5 и JS, и я хотел, чтобы люди могли вставлять пользовательский скрипт, но безопасно.
function executeCustomJS(code){
eval(code);//bad
}
Конечно, этот код очень плох, потому что если код будет чем-то вроде document.location.href='http://meatspn.com'
, то результат станет очень …(…)
Одно из решений, которое я нашел, заключается в экранировании (например, eval
-> ___eval___
) всех ключевых слов и исключении ключевых слов из белого списка, таких как ‘while’, ‘for’, ‘if’, ‘var’, ‘true’, ‘false’, … и ‘func0’, ‘func1’, …., которые являются чем-то вроде API) игры и безопасны.
Например,
function executeCustomJS(code){
code = code.replace(/(Keyword RegEx)/g,'___$1___');
/*unescape keywords in whitelist*/
eval(code);
}
Я не вводил регулярные выражения и прочее в комментарии, но вопрос не в этом.
Давайте предположим, что строки в коде не экранируются, нет функции, которую можно создать путем экранирования строки, а ‘eval’, ‘window’, ‘document’, ‘alert’, ‘location’ отсутствуют в белом списке. Тем не менее, некоторые люди могут выполнять код, подобный while(true){}
, они не могут выполнить какой-либо код, подобный document.location.href='http://meatspn.com'
.
Безопасен ли этот метод? Или, существует ли лучший способ или нет?
Ответ №1:
Я рекомендую вам использовать ограниченный язык сценариев поверх JSON. Итак, задокументируйте механизм сценариев, который требует от вас создания объекта JSON в качестве вашего кода.
Это имеет большое преимущество в том, что в JSON невозможно внедрить неправильный код, потому что это просто данные.
Таким образом, вы можете создать какой-то декларативный синтаксис для вашего скриптового кода. Например
{
"0": {
"Action": "move",
"X": 10,
"Y": -5
},
"1": {
"Action": "emote",
"type": "dance"
}
}
Теперь, что такое хороший дизайн для крошечного декларативного языка сценариев — это совершенно другой вопрос.
Комментарии:
1. Если предполагается, что это JSON, вам нужно обрабатывать имена свойств как строки.
{ "Action": ...
2. Спасибо! (но мне все еще интересно, безопасен ли мой метод ..)
3. @tylermwashburn на самом деле это объектный литерал. Но да, JSON нужны свойства в строках. @JiminP это безопасно, только если вы знаете о javascript больше меня ;). Я вижу ваш анализатор белого списка, вы отправили его мне. Я могу найти в нем все дыры. Вы собираетесь смотреть meatspn снова и снова 🙂
4. @Raynos С помощью объектного литерала вы все равно можете хранить больше данных.
x: function () { bombJapan(); }
5. @tylermwashburn это правда. Но вы не можете создать объектный литерал, содержащий функцию через
JSON.parse
. Идея состоит в том, чтобы загрузить JSON, примером просто оказался объектный литерал, ограниченный JSON. Может быть, мне следует изменить пример на JSON 🙂
Ответ №2:
Предоставьте все, что пользователь может пожелать сделать как combinators
, например, подъязык.
Ответ №3:
https://developers.google.com/caja/
Компилятор Caja — это инструмент для обеспечения безопасности встраивания сторонних HTML, CSS и JavaScript на ваш веб-сайт. Это обеспечивает эффективное взаимодействие между страницей встраивания и встроенными приложениями. Caja использует объектно-ориентированную модель безопасности, обеспечивающую широкий спектр гибких политик безопасности, чтобы ваш веб-сайт мог эффективно контролировать, что встроенный сторонний код может делать с пользовательскими данными.