Как кодировать текст JavaScript внутри атрибута XML? - PullRequest
1 голос
/ 08 июня 2010

У меня есть фрагмент строки JavaScript, полученный из ненадежного источника, встроенный в тег onclick, и я не уверен, каков правильный способ кодирования этой строки.Вот упрощение HTML:

<input type="button" onclick="alert([ENCODED STRING HERE]);"
    value="Click me" />

Я использую библиотеку Microsoft AntiXss , которая содержит несколько методов для кодирования.Текст встроен в атрибут HTML / XML, поэтому представляется целесообразным кодирование атрибута XML с использованием метода AntiXss.XmlAttributeEncode .Тем не менее, это также кусок JavaScript.Поэтому кодировка JavaScript с использованием метода AntiXss.JavascriptEncode также представляется целесообразной.

Какой из них следует выбрать таким образом, чтобы я не выявлял утечку безопасности, при этом позволяябудет отображаться правильно?

ОБНОВЛЕНИЕ: В настоящее время я использую обходной путь, используя XmlAttributeEncode для этого текста и помещая его в пользовательский атрибут в теге.После этого я использую JavaScript для чтения этого тега.В основном это выглядит так:

<input type="button" onclick="alert(this.getAttribute('comment');"
    value="Click me" comment="[XML ATTRIBUTE ENCODED TEXT HERE]" />

Хотя это работает отлично и решает проблему, мне все еще очень любопытно, как правильно кодировать JavaScript внутри атрибута XML.

Ответы [ 3 ]

5 голосов
/ 22 июня 2010

Правильный ответ - двойное кодирование текста.Сначала с JavascriptEncode, а затем с XmlAttributeEncode.Это объясняется тем, что все, что находится в атрибуте xml / html, должно быть закодировано в атрибуте XML.Парсер браузера будет интерпретировать это как атрибут xml и декодировать его таким образом.Браузер будет передавать этот декодированный текст интерпретатору javascript, и поэтому он должен быть правильно закодирован для предотвращения утечки безопасности.

Это двойное кодирование не приведет к недопустимым результатам, поскольку браузер также будет дважды декодировать этот текст (потому что задействованы два отдельных переводчика).Вот пример правильного кодирования.

string unsafeText = "Hello <unsafe> ');alert('xss');alert('";
string javaEncoded = AntiXss.JavascriptEncode(unsafeText, false);
ENCODED_STRING = AntiXss.XmlAttributeEncode(javaEncoded);

<input type="button" onclick="alert('[ENCODED_STRING]');"
    value="Click me" />

Хотя двойное кодирование является единственным правильным способом сделать это, я хотел бы отметить, что использование только кодировки JavaScript обычно дает правильный результат.Здесь ограничение заключается в том, что текст атрибута помещается в кавычки.

Кодировка JavaScript использует тот же белый список (за исключением символа пробела), что и кодировка атрибута HTML / XML.Разница между ними заключается в том, как кодируются небезопасные символы.Javascript кодирует их как \ xXX и \ uXXXX (например, \ u01A3), а атрибут XML кодирует их как & # XX;и & # XXXX;(например, A3;).При кодировании текста с использованием кодировки JavaScript остается только два символа, которые будут снова закодированы кодировщиком атрибута XML, а именно символ пробела и символ обратной косой черты.Эти два символа могут стать проблемой только тогда, когда текст атрибута не заключен в кавычки.

Обратите внимание, однако, что только использование кодирования атрибута XML в этом сценарии НЕ даст правильного результата.

2 голосов
/ 08 июня 2010

Может быть, вам стоит попробовать кодировку base64. Он не будет содержать недопустимых данных в вашем html (как только вы поместите закодированную строку в одинарные кавычки), и вы сможете декодировать ее с помощью javascript.

2 голосов
/ 08 июня 2010

Установите обработчик onclick в отдельном теге <script>.

<input type="button" id="clickMeButton" value="Click me" />

...

<script type="text/javascript">
...
document.getElementById('clickMeButton').onclick = function () {
   alert([ENCODED STRING HERE using AntiXss.JavascriptEncode]);
}
...
</script>
...