Встраивание объектов JSON в теги скрипта - PullRequest
19 голосов
/ 14 ноября 2010

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

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

Допустим, мой объект 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 ]

11 голосов
/ 15 ноября 2010

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

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

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

6 голосов
/ 14 ноября 2010

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

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

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


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

0 голосов
/ 31 июля 2013

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

0 голосов
/ 21 марта 2011

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

<script type='text/javascript'>JSON={"foo": "</" + "script>"};</script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...