Встраивание объектов JSON в теги скрипта

РЕДАКТИРОВАТЬ: для дальнейшего использования, я использую не-xhtml определение типа контента <!html>

Я создаю веб-сайт с использованием Django и пытаюсь встраивать произвольные данные json в мои страницы для использования клиентским JavaScript-кодом.

Допустим, мой объект JSON {"foo": "</script>"}, Если я вставлю это напрямую,

<script type='text/javascript'>JSON={"foo": "</script>"};</script>

Первый закрывает объект json. (также это сделает сайт уязвимым для XSS, так как этот объект json будет генерироваться динамически).

Если я использую escape-функцию HTML в django, результат будет таким:

<script type='text/javascript'>JSON={&quot;foo&quot;: &quot;&lt;/script&gt;&quot;};</script> 

и браузер не может интерпретировать <script> тег.

У меня есть вопрос,

  1. Каких персонажей я должен избежать / не избежать в этой ситуации?
  2. Есть ли автоматический способ сделать это в Python / Django?

4 ответа

Решение

Если вы используете XHTML, вы сможете использовать ссылки на сущности (&lt;, &gt;, &amp;) чтобы избежать любой строки внутри <script>, Вы не хотели бы использовать <![CDATA[...]]> раздел, потому что последовательность "]]>"не может быть выражен в разделе CDATA, и вам придется изменить сценарий для выражения ]]>,

Но вы, вероятно, не используете XHTML. Если вы используете обычный HTML, <script> тег действует как раздел CDATA в XML, за исключением того, что он имеет еще больше подводных камней. Заканчивается </script>, Есть также загадочные правила, позволяющие <!-- document.write("<script>...</script>") --> (комментарии и <script> открывающий тег должен присутствовать как для </script> чтобы пройти через). Компромисс, принятый редакторами HTML5 для будущих браузеров, описан в токенизации HTML 5 и CDATA Escape

Я думаю, что вы должны предотвратить </script> от появления в вашем JSON, и чтобы быть в безопасности, вы также должны избегать <script>, <!--, а также --> для предотвращения побочных комментариев или тегов скрипта. Я думаю, что проще всего заменить < с \u003c а также --> с --\>

Я пробовал обратную косую черту, избегая прямой косой черты, и это, кажется, работает:

<script type='text/javascript'>JSON={"foo": "<\/script>"};</script>

ты пробовал это?


С другой стороны, я удивлен, что встроенный </script> тег в строке нарушает JavaScript. Сначала не мог поверить, но тестировал в Chrome и Firefox.

Для этого случая в Python, я открыл ошибку в трекере ошибок. Однако правила действительно сложны, так как <!-- а также <script> играть вместе довольно злыми способами даже в принятых правилах html5 разбора. Кстати, ">" не является допустимым JSON-escape, поэтому его лучше заменить на "\u003E", поэтому абсолютно безопасным экранированием должно быть экранирование \u003C и \ u003E И пара других злых символов, упомянутых в ошибке в python...

Я бы сделал что-то вроде этого:

<script type='text/javascript'>JSON={"foo": "</" + "script>"};</script>
Другие вопросы по тегам