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

Является ли json_encode достаточной защитой XSS?

У меня есть объект stdClass в PHP, что-то вроде

$o = new stdClass;
$o->foo = $bar

Переменная $bar содержит недоверенную строку.

Является ли следующий код шаблона PHP достаточной защитой XSS

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

Моя первоначальная инстинктивная реакция заключается в том, что является безопасным, поскольку кодирование объекта в виде JSON гарантирует, что любые потенциальные эксплойты JavaScript будут инертными, если их включить в качестве объектов свойств строки JSON. Примерно так

$o = new stdClass;
$o->foo = "<script type=\"text/javascript\">alert(document.cookie)</script>";
?>
<script type="text/javascript">
    var o = <?php echo json_encode($o) ?>;    
</script>    

В результате получается такой

<script type="text/javascript">
    var o = {"foo":"<script type=\"text\/javascript\">alert(document.cookie) <\/script>"};    
</script>    

Если это известно как небезопасный, существует ли стандартный, зрелый способ сериализации простого объекта stdClass в строку JSON для использования в части <script/> HTML-документа.

В ожидании первого быстрого ответа я понимаю, что сработали бы любые HTML-теги или иная XSS-фильтрация каждого элемента объекта JSON, но я ищу краткий способ сделать это. Подобно тому, как это

//$eBar = addslashes($bar);
$sql = sprintf("SELECT * FROM table WHERE foo = '%s'",mysql_real_escape_string($bar));

и это

$sql = $db->select('SELECT * from table where foo = ?', $bar);

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

4b9b3361

Ответ 1

Кажется, что лучший ответ на этот вопрос лежит в другом вопросе.

Подводя итог, PHP JSON-кодер избегает всех несимвольных символов ASCII, поэтому новые строки/возвращаемые каретки не могут быть вставлены в пакетную часть Javascript-строки свойства JSON. Это может быть неверно для других кодеров JSON.

Однако передача исходной строки в JSON-кодирование может привести к обычной атаке XSS-атак, предлагается следующая комбинация констант.

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

или убедитесь, что переменная, переданная в json_encode, действительно является объектом.

Ответ 2

XSS очень широк, и на самом деле невозможно в любой момент узнать, безопасны ли ненадежные данные, которые вы используете.

Ответ на самом деле зависит от ситуации. json_encode не запускается сам по себе - вы используете его только для сериализации. Функция escape, которую вы хотите использовать, будет htmlspecialchars.

Однако зависит от того, хотите ли вы использовать htmlspecialchars. Например, вы введете значение o.foo с помощью innerHTML или textContent? Последнее привело бы к двойному побегу, но первый вложил бы script. Как насчет того, собираетесь ли вы использовать eval (в JS)?

Кстати, addslashes не, функционально эквивалентный экранированию mysql.

Я бы не стал смешивать JavaScript и PHP таким образом, чтобы начать, но это другая история.

Ответ 3

То, что я делаю, - это оценить объект json, прежде чем приступать к его безопасности. Я думаю, что метод evalJSON (true) в прототипе и jquery имеет аналогичную реализацию. Я не очень разбираюсь в стандартах xss с JSON, но это помогает мне

Ответ 4

Как говорили другие ответы; json_encode не создан для защиты от anti-xss. Если вы специально не кодируете небезопасную строку (или дезинфицируете должным образом), у вас будет потенциальная проблема.

Кроме того, после того, как эта строка будет извлечена из объекта JSON, она по-прежнему потенциально опасна, если ее ввести на страницу в любой момент. Например:

<?php $a->foo = "<script>alert(1)</script>"; ?>
var v = <?php echo json_encode($a); ?>

вряд ли будет выполняться (хотя вы не можете быть уверены). Но если вы должны были сделать:

$('#some-element').html(v.foo);

вы абсолютно столкнулись бы с уязвимостью.