Эвал это зло ... Так что я должен использовать вместо этого? - PullRequest
20 голосов
/ 14 марта 2009

Запрос ajax возвращает мне стандартный массив JSON, заполненный входными данными моего пользователя. Ввод был очищен, и с помощью функции eval () я могу легко создать свой объект javascript и обновить свою страницу ...

Так вот в чем проблема. Независимо от того, как сильно я пытаюсь санировать входные данные, я бы предпочел не использовать функцию eval (). Я проверил в Google способы использования «JSON в AJAX без eval» и наткнулся на множество различных методов ...

Какой я должен использовать? Существует ли стандартный, проверенный способ сделать это?

Ответы [ 9 ]

21 голосов
/ 14 марта 2009

json.org имеет хорошую библиотеку JavaScript

простое использование:

JSON.parse('[{"some":"json"}]');
JSON.stringify([{some:'json'}]);

Редактировать : Как указано в комментариях, здесь используется eval, если вы просматриваете его источник (хотя вначале кажется, что его нужно очистить)

чтобы избежать этого, посмотрите на json_parse или json-sans-eval

json2.js небезопасен, json_parse.js медленный, json-sans-eval.js не проверяет

11 голосов
/ 14 марта 2009

Существует ли стандартный, проверенный и надежный способ сделать это?

В следующей версии JavaScript для ECMAScript 3.1 предлагается стандартный способ сделать это: JSON.parse .

Он будет поддерживаться в IE8, Firefox 3.1 / 3.5 и, скорее всего, в других популярных браузерах в будущем. Тем временем вы можете использовать или использовать исключительно eval (). Зло это может или не может быть; конечно, это будет медленнее, чем JSON.parse. Но сегодня это обычный способ анализа JSON.

Если злоумышленник может внедрить вредоносный JavaScript-код в контент, который вы выплевываете через JSON, у вас есть более серьезные проблемы, чем беспокоиться, чем eval-is-evil.

9 голосов
/ 14 марта 2009

Я бы сказал, что после того, как входные данные санированы, eval - лучший путь. Если ваш сервер будет взломан, люди все равно смогут отправлять клиенту любые сценарии, которые они захотят. Таким образом, установка eval не является большой угрозой безопасности. Если вы беспокоитесь о том, что люди манипулируют пакетами до того, как они достигнут клиента, опять же, сами сценарии могут быть изменены.

Не беспокойся об оценке. Но обязательно оберните его в блок try ... catch, чтобы ваши пользователи не получали ошибок JS, если ваш JSON искажен.

:)

2 голосов
/ 14 марта 2009

Чтобы безопасно преобразовать JSON в объект JS, вы должны использовать анализатор JSON, например, функцию JSON.parse (), предоставляемую этой библиотекой .

0 голосов
/ 30 апреля 2012

Проблема: Проблема, которую ставит eval, заключается в том, что он выполняется в глобальной области видимости

eval.call(document, "console.log(this)")
eval.call(navigator, "console.log(this)")
eval.call(window, "console.log(this)")
(function(){eval.call(document, "console.log(this)")})()
>Window

Сценарий:

Предположим, вы используете отдельные атрибуты в коде разметки различных элементов документа, такие как атрибут onvisible

<img src="" onvisible="src='http://www.example.com/myimg.png';">

Вы хотели бы получить все элементы с этим атрибутом, превратить onvisible-content-string в замыкание и поместить его в очередь EventHandler. Здесь вступает в игру конструктор JS Function.

Function === 0..constructor.constructor
>true

Function('return [this, arguments]').call(window, 1,2,3)
>Window, Arguments[3]]
Function('return [this, arguments]').call(document, 1,2,3)
>Document, Arguments[3]]
Function('return [this, arguments]').call(navigator, 1,2,3)
>Navigator, Arguments[3]]    

Собираем все вместе:

var eventQueue = [];
var els = document.querySelectorAll('[onvisible]');

for (var el in els) {
    var jscode = els[el].getAttribute('onvisible');
    eventQueue.push( {el:els[el], cb:Function(jscode)} )
}

//eventQueue[0].cb.call(scope, args);
0 голосов
/ 28 июля 2010

«украдено» из jQuery

// Try to use the native JSON parser first
return window.JSON && window.JSON.parse ?
    window.JSON.parse( data ) :
    (new Function("return " + data))();
0 голосов
/ 04 июня 2009

Если вы уверены, что нет риска инъекции, и вы не eval()ing в цикле, тогда используйте eval(). Он будет выгодно отличаться от других опций, которые, безусловно, будут медленнее, могут сломаться и потребуют от клиента загрузки дополнительного кода.

0 голосов
/ 14 марта 2009

Зависит от того, что вы пытаетесь достичь с помощью санитарии. Я добился больших успехов благодаря поддержке протоколов JSON и безопасной оценки prototype .

0 голосов
/ 14 марта 2009

Сравните с шаблоном разработки команд: http://en.wikipedia.org/wiki/Command_pattern.. С учетом этого вы можете точно определить операции, которые может выполнять клиент, и ваше приложение будет таким же безопасным, как и основная интерпретация.

...