У меня есть объект 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 = sprtinf("SELECT * FROM table WHERE foo = '%s'",mysql_real_escape_string($bar));
и это
$sql = $db->select('SELECT * from table where foo = ?', $bar);
(в большинстве контекстов) функционально эквивалентны, но более поздний считается лучшим, более безопасным кодом, поскольку пользователю конечного программиста не нужно беспокоиться об экранирующих схемах.
Кажется, что лучший ответ на этот вопрос лежит в другом вопросе .
Подводя итог, JSON-кодер PHP избегает всех символов, отличных от 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
, действительно является объектом.
То, что я делаю, – это оценить объект json, прежде чем приступить к его безопасности. Я думаю, что метод evalJSON (true) в прототипе и jquery имеет аналогичную реализацию. Я не знаю много о стандартах xss с JSON, но это помогает мне
XSS очень широк, и на самом деле невозможно в любой момент узнать, безопасны ли ненадежные данные, которые вы используете.
Ответ на самом деле зависит от ситуации. json_encode
не json_encode
сам по себе – вы используете его только для целей сериализации. Функция escape, которую вы хотите использовать, будет htmlspecialchars
.
Однако зависит от того, хотите ли вы использовать htmlspecialchars
. Например, вы будете вставлять значение o.foo
с помощью innerHTML
или textContent
? Последний приведет к двойному побегу, но первый вставляет скрипт. А если вы собираетесь использовать eval
(в JS)?
Кстати, addslashes
не функционально эквивалентно экранированию mysql.
Я бы не стал смешивать JavaScript и PHP таким образом, но это уже другая история.
Как говорили другие ответы; json_encode не создан для защиты от anti-xss. Если вы специально не кодируете небезопасную строку (или дезинфицируете должным образом), у вас будет потенциальная проблема.
Кроме того, после того, как эта строка будет извлечена из объекта JSON, она по-прежнему потенциально опасна, если ее ввести на страницу в любой момент. Например:
<?php $a->foo = "<script>alert(1)</script>"; ?> var v = <?php echo json_encode($a); ?>
вряд ли будет выполняться (хотя вы не можете быть уверены). Но если вы должны были сделать:
$('#some-element').html(v.foo);
вы абсолютно столкнулись бы с уязвимостью.