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

EDIT: для справки в будущем я использую определение типа содержимого не-xhtml <!html>

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

Скажем, мой json-объект {"foo": "</script>"}. Если я вставляю это непосредственно,

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

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

Если я использую функцию запуска django HTML, результирующий вывод:

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

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

Вопрос, который у меня есть,

  • Какие символы я могу избежать/не убежать в этой ситуации?
  • Есть ли автоматический способ выполнить это в Python/django?

Ответ 1

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

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

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

Ответ 2

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

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

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


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

Ответ 3

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

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

Ответ 4

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