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 mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Ответить