Является ли 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 = sprtinf("SELECT * FROM table WHERE foo = '%s'",mysql_real_escape_string($bar)); 

и это

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

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

Solutions Collecting From Web of "Является ли json_encode достаточной защитой XSS?"

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

Подводя итог, 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); 

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