Re: proxy cache key и fastcgi cache key

S.A.N nginx-forum at nginx.us
Sat Jan 11 03:08:00 UTC 2014


> Коллизии возможны только в одном случае: программист не проверяет
> данные,
> получаемые от клиента, и такому программисту никаким костылями не
> поможешь.

Проверять на бекенде значения Host не рационально, если в конфигурации
server указан только один домен.
Если следовать вашей логике тогда, бекенд должен проверять не только Host,
но и IP коннекта чтобы убедится что это коннект от Nginx, так тоже никто не
делает потому что это не рационально, более эффективный способ настроить
фаирвол который закрывает извне доступ к портам бекенда.
Тоже самое с заголовком Host, в том же Apache директива UseCanonicalName On,
во многих дистрибутивах установлена по умолчанию или администраторы её
устанавливают самостоятельно.

Но если вы по прежнему считаете что проверка Host на бекенде, решает все
проблемы вы ошибаетесь, приведу пример.
Есть проект, в котором сайт имеет множество подоменов, каждый подомен
настроен в отдельном server{}.
Бекенд при получении запросов проверяет HTTP_HOST и в соответствии с его
значениям, выполняет разную логику и генерит разные страницы.
Каждый подомен настроен в отдельном server{} индивидуально и оптимизирован
под функционал каждого подомена.

Пример:

server
{
  server_name example.com
  …
  fastcgi_cache use_cache;
  ….
}

server
{
  server_name auth.example.com
  …
}

Как видите в первом вирт хосте есть Nginx кеширования, во втором его нет.

Теперь делаем запрос

GET http://auth.example.com/ HTTP/1.1
Host: example.com

Nginx, определяет вирт хост как auth.example.com в котором нет кешировании и
передает бекенду HTTP_HOST = example.com, бекенд проверяет HTTP_HOST и
генерит страницу для example.com.
Это позволяет устроить Ддос атаку на домен example.com потому что Nginx
будет пропускать все запросы к бекенду без кеширования, бекенд будет
генерить страницу для example.com, тратить свои ресурсы в расчете на то что
страница попадет в кеш Nginx, но этого не случится потому что Nginx выполнил
директивы из одного вирт хоста, но в бекенд передал другое значения Host и
проверка этого значения прошла на бекенде успешно что и требовалось хакерам
для Ддос атаки.

> > Для каждого вирт хоста прописан proxy_cache_key
> $proxy_host$request_uri.
> > 
> > Теперь делаем запрос
> > GET http://apple-shop.com/ HTTP/1.1
> > Host: samsung-shop.com
> > 
> > В результате чего, ответ бекенда сохранится в кеше Nginx с ключом "
> > samsung-shop.com/" но содержать внутри будет страницу
> apple-shop.com/. 
> > На все последующие запросы samsung-shop.com будет отдаваться
> страница с
> > товарами Apple, так как внутри кеш файла с ключом
> "samsung-shop.com/" будет
> > страница хоста apple-shop.com.
> 
> Не будет, если только в обоих случаях не указано:

Т.е вы утверждаете, что значения переменой $proxy_host в данном запросе
будет = apple-shop.com, а не samsung-shop.com?
Сейчас проверить самостоятельно не могу, потому что везде у нас FastCGI.
Но если $proxy_host != $http_host, тогда я не вижу причин не сделать тоже
самое для FastCGI.


>  1. В каком месте документации написано, что надо настраивать так, как
> было
>     указано вами выше?

Вот ссылка на документацию.
http://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_cache_key
По умолчанию значение директивы близко к строке
proxy_cache_key $scheme$proxy_host$uri$is_args$args;

>  2. Как вообще всё вышеописанное вами относится к обсуждаемой в данной
>     подветке теме про http://habrahabr.ru/post/166855/ (которая вообще
>     не относится к кэшу и директивам
> proxy_cache_key/fastcgi_cache_key,
>     но уж так вышло, что была затронута)?

В данном примере, я пытался привести ситуацию где используется
proxy_cache_key (тема нашего треда) и так же запрос с absoluteURI чтобы
показать проблемы описаны в http://habrahabr.ru/post/166855/

В итого хочется сказать, что отсутствия в Nginx аналога UseCanonicalName On,
который есть в Apache, на руку только злоумышленникам, которые будут делать
запросы с absoluteURI и заголовком Host одновременно, в расчете на то что
Nginx выполнит директивы из одного вирт хоста, а бекенд будет выполнять
данный запрос в соответсвии с заголовком Host, который Nginx проигнорировал
в этом и заключается коллизия.

Posted at Nginx Forum: http://forum.nginx.org/read.php?21,246086,246274#msg-246274



Подробная информация о списке рассылки nginx-ru