Хочу поделиться одной особенностью при установке значений COOKIE, которую очень часто забывают веб-разработчики.
В моей практике исследования веб-приложений на уязвимости, за 2009-2011 года, данная ошибка встретилась в 87% веб-приложений, написанных на PHP.
Чтобы как-то уменьшить данный показатель, решил написать этот текст.
Речь пойдет даже не о httpOnly флаге, хотя его использование не менее важно и обязательно к применению.
Рассмотрим пример кода:
Данный код, очевидно, устанавливает два значения COOKIE с именами foo и foo1.
Теперь главный вопрос — для какого домена и с какими флагами?
Обратимся к первоисточнику — HTTP-ответу веб-сервера:
Как видно, сервер ничего не говорит ни о домене, ни о флагах.
Тогда вопрос переходит в другую плоскость — какой домен и флаги выберет браузер для такого заголовка?
В случае с Chrome (актуальная версия 18.0.1025.168), все будет более чем хорошо и домен будет ровно такой, с которого пришел запрос. В моем примере — foo.bar.com:
Если бы все было так хорошо, наверное, здесь бы не было текста…
Проверим Internet Explorer. Так как красивых плагинов для просмотра COOKIE для него я не знаю, проставим куки для домена foo.com и выведем document.cookie с домена bar.foo.com:
Это очень печально. И забавно с другой стороны.
При получении в НТТР-ответе сервера
Атакующему, роль которого мне часто приходится играть при выполнении аудитов, остается найти XSS на любом поддомене целевого хоста, что на практике очень легко реализуется.
А как же остальные браузеры?
Таким образом, используя конструкции
и
в случае использования клиентом Internet Explorer (8-9), вы проставляете COOKIE на ВСЕ поддомены от данного.
Помните об этом!
В моей практике исследования веб-приложений на уязвимости, за 2009-2011 года, данная ошибка встретилась в 87% веб-приложений, написанных на PHP.
Чтобы как-то уменьшить данный показатель, решил написать этот текст.
Речь пойдет даже не о httpOnly флаге, хотя его использование не менее важно и обязательно к применению.
Рассмотрим пример кода:
<?php
setcookie('foo','bar1');
header('Set-cookie: foo1=bar11');
?>
Данный код, очевидно, устанавливает два значения COOKIE с именами foo и foo1.
Теперь главный вопрос — для какого домена и с какими флагами?
Обратимся к первоисточнику — HTTP-ответу веб-сервера:
Как видно, сервер ничего не говорит ни о домене, ни о флагах.
Тогда вопрос переходит в другую плоскость — какой домен и флаги выберет браузер для такого заголовка?
В случае с Chrome (актуальная версия 18.0.1025.168), все будет более чем хорошо и домен будет ровно такой, с которого пришел запрос. В моем примере — foo.bar.com:
Если бы все было так хорошо, наверное, здесь бы не было текста…
Проверим Internet Explorer. Так как красивых плагинов для просмотра COOKIE для него я не знаю, проставим куки для домена foo.com и выведем document.cookie с домена bar.foo.com:
Это очень печально. И забавно с другой стороны.
При получении в НТТР-ответе сервера
Set-cookie: foo=bar
Internet Explorer ставит foo=bar для ВСЕХ поддоменов, то есть *.foo.com в моем примере без всяких флагов, таких как httpOnly.Атакующему, роль которого мне часто приходится играть при выполнении аудитов, остается найти XSS на любом поддомене целевого хоста, что на практике очень легко реализуется.
А как же остальные браузеры?
Firefox | 12.0 | httpOnly | wildcard |
Safari | 5.1.5 | httpOnly | wildcard |
Opera | 11.62 | httpOnly | wildcard |
Таким образом, используя конструкции
setcookie('foo','bar1');
и
header('Set-cookie: foo1=bar11');
в случае использования клиентом Internet Explorer (8-9), вы проставляете COOKIE на ВСЕ поддомены от данного.
Помните об этом!