2016-08-03 3 views
3

Рассмотрим следующий пример ...ColdFusion XSS защиты с 3 контексты все-в-одном

<cfset ascii32to126 = "!""##$%&'()*+,-./:;<=>[email protected][\]^_`abcdefghijklmnopqrstuvwxyz{|}~"> 
<cfoutput> 
    <input type="button" value="Submit" onclick="window.location='xss.cfm?demo1=#encodeForHtmlAttribute(ascii32to126)#'"><br> 
    window.location='xss.cfm?demo1=!"##$%&'()*+,-./:;<=>[email protected][\]^_`abcdefghijklmnopqrstuvwxyz{|}~'<br> 
    OBVIOUSLY THIS ONE IS INCORRECT 
    <br><br> 

    <input type="button" value="Submit" onclick="window.location='xss.cfm?demo1=#encodeForUrl(ascii32to126)#'"><br> 
    window.location='xss.cfm?demo1=%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E%5F%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E' 
    <br><br> 

    <input type="button" value="Submit" onclick="window.location='xss.cfm?demo1=#encodeForHtmlAttribute(encodeForUrl(ascii32to126))#'"><br> 
    window.location='xss.cfm?demo1=%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E%5F%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E' 
    <br><br> 

    <input type="button" value="Submit" onclick="window.location='xss.cfm?demo1=#encodeForHtmlAttribute(encodeForJavaScript(encodeForUrl(ascii32to126)))#'"><br> 
    window.location='xss.cfm?demo1=\u002521\u002522\u002523\u002524\u002525\u002526\u002527\u002528\u002529\u00252A\u00252B\u00252C\u00252D\u00252E\u00252F\u00253A\u00253B\u00253C\u00253D\u00253E\u00253F\u002540ABCDEFGHIJKLMNOPQRSTUVWXYZ\u00255B\u00255C\u00255D\u00255E\u00255F\u002560abcdefghijklmnopqrstuvwxyz\u00257B\u00257C\u00257D\u00257E' 
</cfoutput> 

Я считаю, что последний пример тот, который должным образом защищен от XSS, потому что в конечном счете это приводит к URL (поэтому encodeForUrl), затем сделайте шаг назад, и теперь вы находитесь в контексте JavaScript (так encodeForJavaScript), затем сделайте еще один шаг назад, и теперь вы находитесь в контексте атрибута HTML (так encodeForHtmlAttribute). Я всегда думал, что это процесс, начните с того, как код в конечном итоге будет использоваться и будет работать в обратном направлении. Я правильно понимаю это? Спасибо!

Кроме того, технически encodeForUrl() делает то, что encodeForHtmlAttribute() делает так, что encodeForHtmlAttribute() можно удалить из последней кнопки, и ничего не изменится вообще, но я предпочитаю это делать, потому что это помогает в обучении и понимании.

ответ

3

Да, вложенность контекста - это правильный способ справиться с этим. Однако маловероятно, что результат по самой глубокой кодировке нарушит окружающий контекст, потому что функции ESAPI максимально строги, а экранирование не перекрывается в этих контекстах. Поэтому, если вам не нужно обрабатывать ненадежный ввод, нет необходимости вставлять кодировки.

encodeForHtmlAttribute(encodeForJavaScript(encodeForUrl(ascii32to126)))

Пример:

encodeForURL("&") 
>> %26 

encodeForJavaScript("&") 
>> \x26 

encodeForHTML("&") 
>> &amp; 

Все управляющие символы здесь безопасны для других контекстах. % безопасен в JavaScript и HTML. \ безопасен по URL и HTML. &#; безопасен по URL и JavaScript. Это не обязательно означает, что вывод будет отображаться правильно, но, по крайней мере, он будет интерпретироваться как буквальная строка и не подвергает опасности безопасности.

Заключение: Использование только encodeForUrl("1&b=2&c=3") в моем примере ниже является достаточным для обеспечения безопасности в отношении XSS, поскольку кодированный вывод является литеральной строкой в ​​JavaScript и HTML и правильно декодируется как URL-адрес.


ПРИМЕЧАНИЕ: Мой первоначальный ответ был основан на устаревшей установке серверной ColdFusion 10. Тогда вход в encodeFor функций нормализовались/канонизированный и таким образом сделал вложенность угрозы безопасности, так как только последний звонок был фактически кодируя вход.

Нет, вложенная кодировка сделает вас уязвимыми (если и только если вход для каждой функции кодирования нормализован, см. Комментарии).

Рассмотрим следующий демонстрационный пример:

<cfset qs = encodeForHtmlAttribute(encodeForJavaScript(encodeForUrl("1&b=2&c=3")))> 

<cfoutput> 
    <button onclick="window.location='index.cfm?a=#qs#'">click me</button> 
</cfoutput> 
<cfdump var="#URL#"> 

Это приведет к 3 отдельных параметров запроса (a, b, c), хотя желательно значение 1&b=2&c=3 в одном параметре запроса a. Причина в том, что: нормализация. Функции кодера будут нормализовать входные данные перед кодированием, чтобы предотвратить атаки с двойным кодированием.

Теперь давайте попробуем кодирующее фактический контекст только один раз:

<cfset qs = encodeForUrl("1&b=2&c=3")> 

<cfoutput> 
    <button onclick="window.location='index.cfm?a=#qs#'">click me</button> 
</cfoutput> 
<cfdump var="#URL#"> 

Encoding раз достаточно, потому что экранирующие символы не перекрывают друг друга в этих контекстах.

+0

Я думаю, вы хотели сказать 'a', а не' x'. Я выполнил ваш первый пример, и это не приводит к 3 отдельным параметрам запроса для меня. Просмотр источника на кнопке показывает это: '', который при нажатии приводит к этому в URL-адресе браузера: 'index.cfm? a = 1% 26b% 3D2% 26c% 3D3', что приводит к просто' a' со значением '1 & b = 2 & c = 3'. Я что-то упускаю? Благодаря! – gfrobenius

+0

Честно говоря, я был также удивлен этим наблюдением, потому что функции кодирования не канонизируются по умолчанию в соответствии с документами. Я выполнил приведенный выше пример установки по умолчанию для CF10. – Alex

+0

Контекст вложенности является теоретически правильным, но поскольку все функции кодирования ESAPI максимально строги, маловероятно, что один из них будет иметь неприятные последствия. Однако, зная, что вышеуказанный код может случиться с вашим CF-сервером, представляется рискованным запускать вложенную кодировку. – Alex

Смежные вопросы