Всем привет. Предположим, что у меня на сайте есть XSS.
Если взломщик добьётся чтобы на моём сайте выполнился яваскрипт пока я нахожусь в админке сайта, последствия могут быть печальными.
Для защиты от этого в админке своей CMS я тщательно проверял http-referer. Например POST-запрос на добавление страницы сайта можно было сделать только если referer соответствовал URL по которому отображалась форма добавления страницы.
Такую защиту я придумал давно, но с тех пор многое изменилось. Сейчас все современные браузеры позволяют менять URI страницы динамически с помощью яваскрипта, как это например делается вконтакте. Сменить URI очень просто таким вот яваскриптом:
Получается, что если на сайте есть xss-то уже ничего не спасёт от взлома. Я проверял во всех браузерах, при смене URI таким способом referer становится таким, каким он будет указан в третьем аргументе функции pushState(). Никаких специфических http-заголовков по которым можно-бы было определить pushState() при этом браузер не отправляет.
Предлагаю обсудить варианты защиты от этого вектора атаки.
Не предлагать:
Если взломщик добьётся чтобы на моём сайте выполнился яваскрипт пока я нахожусь в админке сайта, последствия могут быть печальными.
Для защиты от этого в админке своей CMS я тщательно проверял http-referer. Например POST-запрос на добавление страницы сайта можно было сделать только если referer соответствовал URL по которому отображалась форма добавления страницы.
Такую защиту я придумал давно, но с тех пор многое изменилось. Сейчас все современные браузеры позволяют менять URI страницы динамически с помощью яваскрипта, как это например делается вконтакте. Сменить URI очень просто таким вот яваскриптом:
Код |
---|
window.history.pushState(null, null, '/admin.php?module=pages&action=newpage'); |
Получается, что если на сайте есть xss-то уже ничего не спасёт от взлома. Я проверял во всех браузерах, при смене URI таким способом referer становится таким, каким он будет указан в третьем аргументе функции pushState(). Никаких специфических http-заголовков по которым можно-бы было определить pushState() при этом браузер не отправляет.
Предлагаю обсудить варианты защиты от этого вектора атаки.
Не предлагать:
- Писать код без XSS. Ежу понятно что писать надо правильно и безопасно, но люди не идеальны и когда кода много где-то да могут ошибиться.
- Админить сайт в приватной вкладке. Это не полноценное решение.
- Использовать CSRF-токен. Это не решение проблемы, так как при CSRF-токен можно подхватить с помощью xmlhttprequest. Не допускать запрос админки сайта через xmlhttprequest идея хорошая, но также не является полноценным решением проблемы.
- Запрещаю открытие админки сайта во фрейме
- Запрещаю загрузку админки через xmlhttprequest
- Делаю проверку referer
- В <head> тег всех страниц сайта добавляю яваскрипт который убирает метод window.history.pushState() таким образом:
Код window.history.pushState = function() {alert('pushState() function restricted');}
Изменено: Pascal9x - 08.02.2014 19:14:59