Json: PHP в JavaScript безопасен или нет? - PullRequest
8 голосов
/ 25 июля 2011

Я понимаю, что использование eval(json_str) на клиенте уязвимо для вредоносного кода. У меня вопрос: если бы json_str был массив, построенный функцией PHP json_encode, был бы я в безопасности?

Например,

json_str = json_encode(array(record1, 
                             record2, 
                             record3));

теперь было бы совершенно безопасно использовать eval(json_str) внутри клиентского кода?

Ответы [ 5 ]

19 голосов
/ 25 июля 2011

С точки зрения чистого JavaScript, да, вы в безопасности: вывод json_encode никогда не может содержать ничего, кроме статических значений, которые не будут иметь неожиданной стороны при передаче в eval.(Хотя при использовании eval вам обычно приходится окружать строку JSON (), чтобы избежать неправильного толкования литерального выражения объекта как блока операторов.)

В сторону: это не обязательно верно для всех JSONкодировщики, потому что есть некоторые символы, которые допустимы для включения raw в строку JSON, которые недопустимы raw в JavaScript.В частности, U + 2028 и U + 2029, которые не могут быть скрыты в строковых литералах JavaScript, поскольку они представляют собой переводы строки.Однако кодировщик PHP кодирует все не-ASCII-символы (например, "\u2028"), поэтому здесь нет проблем.

С точки зрения JavaScript, встроенного в другой язык (обычно HTML), вы не обязательно в безопасности.Например:

<script type="text/javascript">
    var v= <?php echo json_encode($value); ?>;
</script>

В этом примере, что если value содержит строку с последовательностью символов </script?Это позволило бы значению преждевременно завершить блок скрипта и таким образом попасть в разметку HTML, где оно могло бы затем внедрить другой вредоносный скрипт.

Чтобы избежать этой проблемы, при включении содержимого JSON в HTML всегда кодируйте < символ в строковых литералах, например \x3C или, в JSON-совместимых терминах, \u003C.Для совместимости со скриптовыми блоками XHTML, отличными от CDATA, выполните также &.Для совместимости с JS внутри атрибутов обработчика событий также делайте кавычки.

PHP сделает это за вас с правильными опциями json_encode():

var v= <?php echo json_encode($value, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS); ?>;

(Вы можете определитьфункция быстрого доступа для ускорения записи.)

2 голосов
/ 20 июня 2015

Если вы хотите использовать Политика безопасности контента (CSP) , вам запрещается выполнять встроенные теги сценария. Следовательно, это сделало бы невозможным в противном случае удивительный ответ Бобинса , поскольку CSP требует, чтобы весь JavaScript был в отдельных файлах.

Как получить свой JavaScript в отдельном файле:

Одним из способов решения этой проблемы является HTML-кодирование JSON с помощью PHP (что должно препятствовать XSS), а затем отображение его в скрытом элементе и использование JavaScript для получения содержимого этого тега (адаптировано из OWASP ):

Поместите это в строку (обратите внимание, что на самом деле это не будет выполнено):

<script id="jsonString" type="application/json">
<?php
// OWASP uses a <script> tag with an invalid "type" attribute, but 
// you can just as easily use a <span style="display:none"> or other
// hidden tag.
//
// Note, this probably won't actually be valid JSON because we are using 
// htmlspecialcharacters() on the JSON data. That doesn't matter because
// this is never actually executed by the browser due to the incorrect
// script type. We will decode it later into valid JSON.
echo htmlspecialchars(json_encode($object), ENT_NOQUOTES); 
?>
</script>

Тогда в вашем файле JavaScript:

var dataElement = document.getElementById('jsonString');
// Get innerText, which also has the side effect of html decoding
// the string returned, which is just what we want
var jsonString = dataElement.textContent || dataElement.innerText;
// Now you can parse the JSON string
var jsonObj = JSON.parse(jsonString);
1 голос
/ 25 июля 2011

Не использовать eval для анализа JSON

Не делай этого.

Весьма вероятно, что ваш сервер никогда не будет взломан, и что ваше приложение будет в основном защищено, бла-бла-бла, дело не в этом. возможно для сервера, который может быть частично скомпрометирован (слишком много векторов атаки, что, если функция php json_encode скомпрометирована на вашем сервере?).

Простое решение - не доверять чему-либо , отправленному кем-либо . Современные браузеры имеют встроенные анализаторы JSON, а www.json.org предоставляет длинный список анализаторов JSON для различных языков. Версии JS будут опираться на нативную реализацию для скорости.

Все это означает, что нет веской причины использовать eval для анализа JSON.

0 голосов
/ 25 июля 2011

Да и нет:

Да: PHP выдает действительный JSON

Нет: PHP может также возвращать вредоносный код, как и в JSON.

Если вы можете доверять источнику или если у вас есть полный контроль над ним (потому что он ваш), проблем не будет.

0 голосов
/ 25 июля 2011

Это должно быть безопасно, но на клиенте вам не гарантируется, что json_str не был введен каким-либо другим источником.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...