Re: Об одной малоизвестной уязвимости в веб сайтах
    S.A.N 
    nginx-forum at nginx.us
       
    Mon Jun 16 19:36:38 UTC 2014
    
    
  
> > Maxim Dounin Wrote:
> > -------------------------------------------------------
> > > Какая-либо проблема появляется тогда и только 
> > > тогда, когда администратор начинает писать в конфиге $http_host, 
> > > не думая о последствиях.  Есть мнение, что совсем простое решение 
> > > этой проблемы - не делать так (c) анекдот.
> > 
> > Вся проблема в том что сами программисты Nginx в модуле FastCGI
> используют
> > переменную $http_host для HTTP_HOST, вместо нормализованной
> переменой $host,
> > администраторам на оборот приходится исправлять это своими руками и
> писать в
> > конфиге
> > fastcgi_param  HTTP_HOST  $host;
> > Если следовать вашей логике, надо изменить код модуля FastCGI, чтобы
> по
> > умолчанию Nginx был вполне себе безопасный.
> 
> По умолчанию в fastcgi http-заголовки передаются как есть, в виде 
> параметров HTTP_*.  Каноническое же имя сервера доступно в 
> параметре SERVER_NAME.  Что из этого и как использовать - это 
> вопрос к приложению, а не к nginx'у.
Я знаю, и уже выше объяснял почему бекенд-приложениям нужно использовать
HTTP_HOST вместо SERVER_NAME.
Значения SERVER_NAME не может использоваться, если в директиве server_name
используется маска или бекенд обрабатывает запросы для default_server.
Ещё раз приведу пример, в котором мы легко можем получить доступ, к закрытым
на уровне Nginx ресурсам.
server
{
  server_name *.example.com;
  ...
  fastcgi_pass php;
}
server
{
  server_name private.example.com;
  location / {
      allow 192.168.1.0/24;
      deny all;
      fastcgi_pass php;
      auth_request /auth;
    }
    ...
 }
Как видно два хоста используют один upstream, на котором бекенд приложения
даёт расширенные привилегии юзерам private.example.com, в расчете на то что
Nginx предварительно сделал проверку по IP и успешно провел аунтификацию,
всё вроде логично и удобно сделано, но такая схема легко ломается таким
запросом.
GET http://example.com/SecureData/ HTTP/1.1
Host: private.example.com
Бекенд получает HTTP_HOST=private.example.com, даёт юзеру привилегии, но
Nginx не проводил проверки по IP и не делал запрос аунтификацию, потому что
отработал хост конфигурации для example.com вместо private.example.com
В данном случаи можно было бы использовать переменную SERVER_NAME, но я выше
писал почему это не всегда возможно.
Если мы оба понимаем, что ситуация когда authority component и значения Host
разные, это исключительная ситуация и её нужно обрабатывать как Exception, в
этом случаи есть три варианта поведения, выбросить Exception (отдать 400
статус), исправить ошибку (использовать переменую $host), и самый плохой
вариант (антишаблон) ничего не делать и не обрабатывать эту исключительную
ситуацию и оставить все как есть.
Posted at Nginx Forum: http://forum.nginx.org/read.php?21,246086,250896#msg-250896
    
    
Подробная информация о списке рассылки nginx-ru