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