Re: Об одной малоизвестной уязвимости в веб сайтах
Gena Makhomed
gmm at csdoc.com
Tue Jun 17 10:35:52 UTC 2014
On 17.06.2014 10:00, Maxim Dounin wrote:
>> Значения SERVER_NAME не может использоваться,
>> если в директиве server_name используется маска
>> или бекенд обрабатывает запросы для default_server.
> Если SERVER_NAME нельзя использовать - значит, необходимо
> передать дополнительный параметр, который и использовать.
Именно для этого и существует HTTP_HOST - передать
значение заголовка Host из валидного клиентского запроса.
> Использовать HTTP_* поля для чего-то, что позволяет
> "получить доступ" - это неправильно.
Если nginx не будет отправлять на backend невалидные клиентские запросы
- проблем с заголовком HTTP_HOST не будет никаких, - он будет валидным.
> Проблема в том, что приложение некорректно предполагает, что
> HTTP_HOST=private.example.com чем-то отличается от других. Как
> показывает пример запроса выше - это не так. И "не так" - не
> только в nginx'е, но и в других серверах.
А мы никаких других веб-серверов кроме nginx и не используем.
В IIS например, багов еще больше, чем в Apache, и что с того?
> Не надо себя обманывать и пытаться закрыть nginx'ом небезопасную
> логику приложения - это не работает и рано или поздно выстрелит.
Приложение было написано в соответствии со стандартами HTTP/1.1
и ожидало, что nginx не пропустит на backend невалидный запрос.
> Правильное решение - передавать информацию о произошедшей
> авторизации явно и отдельно (или пользоваться параметром
> SERVER_NAME, который уже передаётся и предназначен специально для
> идентификации сервера).
server {
server_name www.example.com example.com;
// ...
}
на backend в переменной SERVER_NAME уйдет всегда www.example.com
вне зависимости от того, к какому именно вирт. хосту был запрос.
переменную HTTP_HOST использовать нельзя.
неужели надо всем делать workaround
fastcgi_param X_REAL_HTTP_HOST $host;
и потом использовать переменную X_REAL_HTTP_HOST вместо HTTP_HOST ?
> Возможно, когда-нибудь мы и придём к тому,
> что в таких ситуациях будет возвращаться 400.
Что мешает сделать это прямо сейчас?
> Но это ни коим образом не избавляет
> от необходимости исправить приложение.
Сейчас - приходится имена виртуальных хостов прописывать
в двух местах - в настройках nginx и в настройках самого
приложения. И дополнительно валидировать HTTP_HOST, проверяя
входит ли это имя в список имен, которые были указаны в директиве
server_name, и были повторно прописаны в настройках приложения.
И если нет - то явно возвращать клиенту статус 400 Bad Request.
Есть стойкое ощущение, что это может и даже должен делать nginx.
Тогда имена хостов надо будет настраивать всего в одном конфиге.
Добавить этот workaround во все backend`ы, которые есть в мире -
это нереально, гораздо проще добавить валидацию запроса в nginx.
--
Best regards,
Gena
Подробная информация о списке рассылки nginx-ru