Встраивание объектов 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={"foo": "</script>"};</script>
и браузер не может интерпретировать тег <script>
.
Вопрос, который у меня есть,
- Какие символы я могу избежать/не убежать в этой ситуации?
- Есть ли автоматический способ выполнить это в Python/django?
Ответы
Ответ 1
Если вы используете XHTML, вы сможете использовать ссылки на объекты (<
, >
, &
), чтобы избежать любой строки, которую вы хотите, в <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...