Является ли JSON.parse() более безопасным, чем eval(), когда веб-страница и вызов ajax поступают с одного сервера?

Я получаю, что JSON.parse() не позволяет злоумышленнику вставлять javascript в ответ, поскольку парсер JSON - это просто синтаксический анализатор, а не синтаксический анализатор script, поэтому, пожалуйста, не закрывайте, это дублирует все остальные вопросы, которые говорят об этом. Это другой вопрос.

Если злоумышленник может заблокировать ваш вызов Ajax и поместить javascript в вызов Ajax, разве они не смогут захватить вашу фактическую веб-страницу и помещать произвольный javascript на вашу страницу, из которой они могут выполнить ту же самую атаку?

Конечно, вам нечего терять, используя JSON.parse() вместо eval() (если у вас еще нет парсера JSON еще в вашей среде и вам нужно добавить больше кода для его получения), но какие ситуации действительно ли это повышает безопасность, если ваша веб-страница обслуживается тем же хостом, что и ваш вызов ajax?

Ответ 1

Да, это действительно безопаснее. Каждая предосторожность, которую вы не принимаете, представляет собой набор потенциальных эксплойтов, которые вы не предотвращаете.

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

Возможно, у кого-то, кто работает на вашем сервере, плохой день, и он делает что-то глупое, как создание JSON путем объединения несаминированного пользовательского ввода:

<?php
    print '{"foo": ' . $_GET['bar'] . '}';
?>

Если вы используете JSON.parse, самое худшее, что они могут сделать, - это переместить большой объект в вашу память. Если вы используете eval, они могут захватить все.

Ответ 2

Хорошо, если они смогут вставлять ваши ответы AJAX, они, вероятно, уже успешно справились с вами по-разному (ARP, DNS или что-то еще).

Подробнее об этих типах атаки см. http://en.wikipedia.org/wiki/Man-in-the-middle_attack.

Вы правы в том, что, если они могут вводить ваш ответ AJAX, они могут также вводить целые страницы. На самом деле все, что вы получаете или отправляете по сети, теперь уязвимо в MitM, если не используется что-то вроде HTTPS\SSL.

Ответ 3

Это очень хороший момент. Единственное, о чем я могу думать, это то, что JSON.parse будет иметь возможность быть быстрее, чем eval.

Менее вероятным преимуществом является то, что браузер уже имеет кешированный HTML/JavaScript, и сервер использует Cache-Control, чтобы сказать, что его не нужно перезагружать. Если это произойдет, то, конечно, перехват человека не будет иметь возможности изменить страницу. Но это очень редкий набор обстоятельств. Скорее всего, вам потребуется браузер для проверки более новой версии HTML/JavaScript, которая является поведением по умолчанию.

Что касается разницы в безопасности, я думаю, что вы правы.

Как и я, я работаю только с системами, поддерживающими HTTPS. Но у меня есть функция, которая использует JSON.parse, если она доступна, и возвращается на eval только для улучшения скорости.

Ответ 4

Ну... Я не сторонник использования eval, но я не думаю, что он представляет собой проблему безопасности в Javascript, потому что Javascript - это клиентский язык. Если вы не используете eval в своем коде, что мешает мне запускать javascript:my_own_evil_code() в консоли или адресной строке? Это Javascript, я могу запускать свой собственный код или изменять свой, создавать свои собственные HTTP-запросы и делать что-либо с ответами HTTP или даже добавлять свои собственные eval к вашим функциям.

Нельзя использовать eval, если доступно другое сопоставимое решение, но если вы просто для простоты захотите сделать eval('('+jsonstring+')') для эмуляции JSON.parse, я не думаю, что это большая ошибка.