Подтвердить что ты не робот

Каков правильный способ кодирования встроенного javascript-объекта, чтобы защитить его от XSS?

Получается следующее, которое выглядит как действительный javascript, а не:

<html> 
<body>
<script>
 json = {test: "</script><script>alert('hello');</script>"};
</script>
</body>
</html>

Тот же текст, когда возвращается JSON через ajax api работает так же, как ожидалось. Однако при оказании встроенных результатов возникают основные проблемы XSS.

Учитывая произвольную правильную строку JSON, что мне нужно сделать на стороне сервера, чтобы сделать ее безопасной для встроенного рендеринга?

ИЗМЕНИТЬ В идеале я хотел бы, чтобы исправление работало со следующей строкой:

json = {test: "<\/script><script>alert('hello');<\/script>"};

Смысл, я понятия не имею, как моя базовая библиотека кодирует / char, возможно, она выбрала его для кодирования или, возможно, нет. (поэтому его вероятное исправление regex более надежное)

4b9b3361

Ответ 1

Для начала, это не JSON вообще, это объект Javascript. JSON - текстовый формат, основанный на синтаксисе Javascript.

Вы можете либо убедиться, что код не содержит комбинацию символов </:

var obj = { test: "<"+"/script><script>alert(\"hello\");<"+"/script>" };

Или, если вы используете XHTML, вы можете убедиться, что содержимое в теге script интерпретируется как простые данные:

<script type="text/javascript">
//<![CDATA[
var obj = { test: "</script><script>alert(\"hello\");</script>" };
//]]>
</script>

Ответ 2

См. Руководство по предотвращению OWASP XSS (см. правило № 3) -

За исключением буквенно-цифровых символов, избегать всех символов менее 256 с форматом \xHH для предотвращения выключение значения данных в контекст script или в другой атрибут. Не используйте никаких экранов ярлыки вроде \", потому что цитата символ может быть сопоставлен HTML который сначала выполняется.

Предположим, что так выглядит ваш объект -


var log = {
trace: function(m1, m2, m3){},
debug: function(m1, m2, m3){},
currentLogValue : "trace {].a23-%\/^&",
someOtherObject : {someKey:"somevalue", someOtherKey:"someothervalue"}
};

Это должно закончиться следующим образом:


var log = {
trace : "function\x28m1,\x20m2,\x20m3\x29\x7B\x7D",
debug : "function\x28m1,\x20m2,\x20m3\x29\x7B\x7D",
currentLogValue : "trace\x20\x7B\x5D.a23\x2D\x25\x5C\x2F\x5E\x26",
someOtherObject : {someKey : "somevalue", someOtherKey:"someothervalue"}
};

Правила просты -

  • Неверные данные разрешены только в паре кавычек
  • Все, что находится в кавычках, сбрасывается следующим образом: "Кроме буквенно-цифровых символов, избегайте всего остального с помощью формата \xHH"

Это гарантирует, что ненадежные данные всегда интерпретируются как строка, а не как функция/объект/что-то еще.

Ответ 3

В литеральных строках поместите обратную косую черту (\) перед всеми "небезопасными" символами, включая косую черту, которая встречается в "</script>" (/\/).

Это изменит ваш пример на:

json = {test: "<\/script><script>alert(\"hello\");<\/script>"};

и он все равно будет действительным JSON.

Конечно, вам также нужно избежать двойной кавычки ("\") и самой обратной косой черты (\\\), но у вас уже будет все равно. Вы также должны рассмотреть возможность избежать одиночной кавычки ('\'), чтобы быть в безопасности.

Ответ 4

Одной из проблем, с которыми вы могли столкнуться, является тот факт, что интерпретаторы HTML и javascript в браузере работают с чередованием.

<html> 
<body>
<script>
 json = {test: "</script><script>alert('hello');</script>"};
</script>
</body>
</html>

В вашем примере интерпретатор HTML предоставит json = {test: " интерпретатору js, а затем найдет следующий блок javascript (разделенный тегами <script> и </script>) и передаст alert('hello'); интерпретатору js. Не имеет значения, что тег </script> находится в строке javascript, потому что интерпретатор HTML является тем, который ищет js-блоки кода и не понимает строки js.

Первый раздел вызовет синтаксическую ошибку js, а вторая секция создаст предупреждение. Я понимаю, что это не отвечает на ваш вопрос о том, что делать, но, возможно, он проливает больше света на то, что происходит под капотом.

Ответ 5

Я нашел этот > список символов, которые будут экранированы для строк JSON:

\b  Backspace (ascii code 08)
\f  Form feed (ascii code 0C)
\n  New line
\r  Carriage return
\t  Tab
\v  Vertical tab
\'  Apostrophe or single quote
\"  Double quote
\\  Backslash character

Использование PHP? Если да: json_encode

 echo json_encode("<\/script><script>alert(\"hello\");<\/script>");

Вывод:

 "<\\\/script><script>alert(\"hello\");<\\\/script>"

Другой пример:

 echo json_encode("</script><script>alert(\"hello\");</script>");

Вывод:

 "<\/script><script>alert(\"hello\");<\/script>"