Как защитить сервер от уязвимости HTTPoxy

18 июля 2016 была обнаружена уязвимость CGI HTTPoxy. Она позволяет злоумышленнику передать HTTP-заголовок Proxy вместе с запросом и таким образом изменить URL, с помощью которого приложение обращается к сервису бэкенда, благодаря чему злоумышленник может похитить учетные данные, изменить ответы, которые сервер отправляет приложению, и т.д.

Причиной уязвимости является конфликт имён между переменной среды HTTP_PROXY, с помощью которой определяется прокси-сервер на бэкенде, и клиентским HTTP-заголовком Proxy. Спецификация CGI отправляет все клиентские хедеры с префиксом HTTP_, в связи с чем и возникает конфликт. Если приложение или библиотека CGI читают эту переменную без дополнительной обработки, они могут использовать предоставленные клиентом значения при попытке подключения к прокси-серверу.

Данная уязвимость содержится во множестве CGI-подобных реализаций, потому для неё разработан ряд идентификаторов:

Исходные формы HTTPoxy были обнаружены ещё в 2001 году, но они никогда не рассматривались в качестве одной широко распространенной уязвимости. К счастью, этот баг довольно просто устранить.

Уязвимые серверы и приложения

HTTPoxy является общей уязвимостью CGI и присутствует почти в каждом приложении CGI.

Уязвимыми являются серверы и приложения, которые:

  • Используют переменную среды HTTP_PROXY для настройки соединений с прокси-сервером. Это стандартный метод настройки прокси-серверов, который присутствует либо в самом коде приложения, либо в библиотеках.
  • Отправляют запросы бэкенду с помощью HTTP. Поскольку причиной конфликта имён является префикс HTTP_, уязвимость затрагивает только приложения, которые используют протокол HTTP. Приложения, использующие HTTPS или другие протоколы, не содержат этого бага.
  • Работают в CGI или CGI-подобном окружении. Уязвимость присутствует во всех приложениях, которые переводят клиентские хедеры в переменные среды с префиксом HTTP_. Уязвима любая CGI-совместимая реализация или связанный с CGI протокол (например, FastCGI).

Как видите, чтобы приложение стало уязвимым, в нём должно присутствовать несколько конкретных факторов. Чтобы проверить на уязвимость своё приложение, перейдите на этот сайт (автор Luke Rehmann).

Уязвимость в языках программирования

Обязательной проверке на уязвимость подлежат приложения, написанные в PHP, поскольку CGI гораздо чаще используется в экосистеме PHP, чем в других языках программирования. Кроме того, тут проблему усугубляют популярные библиотеки, которые широко используют метод getenv. В частности, на данный момент уязвимы Guzzle (версия 4.0.0rc2 и выше), Artax и класс программы Composer под названием StreamContextBuilder.

Также баг присутствует в языках Python и Go. Как правило, при развёртывании приложений Python и Go используется не HTTP, потому большинство приложений, написанных на этих языках, не подвержено уязвимости. Однако если приложение развёрнуто с помощью CGI, то все библиотеки, которые по умолчанию используют переменную HTTP_PROXY, будут уязвимы.

Как устранить баг HTTPoxy

К счастью, ошибку HTTPoxy достаточно просто устранить. Это делается на уровне веб-сервера, приложения или библиотеки.

  • Приложения или библиотеки могут игнорировать переменную HTTP_PROXY, находясь в среде CGI.
  • Приложения или библиотеки могут использовать другие переменные среды для настройки соединения с прокси-сервером.
  • Веб-серверы или прокси-серверы могут сбрасывать клиентский заголовок Proxy.

При использовании уязвимой библиотеки необходимо смягчить угрозу на стороне сервера, пока библиотека не предоставит патчи. Если вы сами разрабатывали библиотеку или приложение и ваш проект использует переменную HTTP_PROXY, рассмотрите возможность использования альтернативной переменной, которая не конфликтует при работе в среде CGI. Ruby и некоторые другие проекты используют для этого CGI_HTTP_PROXY.

Хедер Proxy не является стандартным хедером HTTP, потому в большинстве случаев его можно просто игнорировать. Для этого нужно настроить веб-сервер или балансировщик нагрузки для сброса этого хедера. Сбрасывать указанные заголовки может любой простой веб-сервер, балансировщик или прокси-сервер.

Удаление HTTP-хедера Proxy в Apache

Веб-сервер Apache сбрасывает хедеры с помощью модуля mod_headers.

Серверы Ubuntu и Debian

Чтобы включить mod_headers, введите:

sudo a2enmod headers

Откройте глобальный файл конфигурации:

sudo nano /etc/apache2/apache2.conf

В конец файла добавьте строки:

. . .
RequestHeader unset Proxy early

Сохраните и закройте файл.

Проверьте синтаксис на ошибки:

sudo apache2ctl configtest

Если ошибок нет, перезапустите сервис:

sudo service apache2 restart

Серверы CentOS и Fedora

Обычно модуль mod_headers включен по умолчанию. Чтобы настроить игнорирование хедера Proxy, откройте глобальный файл конфигурации:

sudo nano /etc/httpd/conf/httpd.conf

В конце вставьте:

. . .
RequestHeader unset Proxy early

Проверьте синтаксис на ошибки:

sudo apachectl configtest

Если ошибок нет, перезапустите сервис:

sudo service httpd restart

Удаление HTTP-хедера Proxy в Nginx

Серверы Ubuntu и Debian

На серверах Ubuntu и Debian параметры FastCGI обычно хранятся в файлах fastcgi_params or fastcgi.conf и извлекаются из них при настройке прокси-сервера FastCGI. Отключить хедер HTTP_PROXY можно в любом из этих файлов.

echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi.conf
echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a  /etc/nginx/fastcgi_params

Если в настройках прокси вы не ссылаетесь ни на один из этих файлов, добавьте в location прокси-сервера следующую строку (файл /etc/nginx/sites-enabled/your_site.conf).

. . .
location ~ \.php$ {
. . .
fastcgi_param HTTP_PROXY "";
. . .
}
}

Если вы используете Nginx как обычный HTTP прокси-сервер, вам нужно удалить хедер Proxy. HTTP-хедеры проксирования устанавливаются файле /etc/nginx/proxy_params. Чтобы сбросить заголовок Proxy, нужно добавить правило:

echo 'proxy_set_header Proxy "";' | sudo tee -a /etc/nginx/proxy_params

Если вы не ссылаетесь на этот файл в настройках сайта (в блоке server), добавьте в блок location прокси-сервера следующую строку:

. . .
location /application/ {
. . .
proxy_pass http://127.0.0.1;
proxy_set_header Proxy "";
. . .
}
}

Проверьте синтаксис на ошибки:

sudo nginx -t

Если ошибок нет, перезапустите сервис:

sudo service nginx restart

Серверы CentOS и Fedora

На серверах CentOS и Fedora для настройки проксирования FastCGI веб-сервер Nginx использует те же файл ы fastcgi_params и fastcgi.conf. отключите хедер HTTP_PROXY в обоих файлах:

echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a /etc/nginx/fastcgi.conf
echo 'fastcgi_param HTTP_PROXY "";' | sudo tee -a  /etc/nginx/fastcgi_params

Если в блоке server сайта вы не ссылаетесь ни на один из этих файлов, добавьте в location прокси-сервера следующую строку (файл /etc/nginx/sites-enabled/your_site.conf).

. . .
location ~ \.php$ {
. . .
fastcgi_param HTTP_PROXY "";
. . .
}
}

Если вы используете Nginx как обычный HTTP прокси-сервер, вам нужно удалить хедер Proxy. Чтобы сбросить заголовок Proxy, нужно добавить следующее правило в каждый location, где выполняется proxy_pass. Если вы не знаете, где именно используется proxy_pass, выполните поиск по каталогу конфигураций:

grep -r "proxy_pass" /etc/nginx
/etc/nginx/nginx.conf.default:        #    proxy_pass   http://127.0.0.1;

Все незакомментированные строки proxy_pass необходимо отредактировать следующим образом:

. . .
location /application/ {
. . .
proxy_pass http://127.0.0.1;
proxy_set_header Proxy "";
. . .
}
}

Проверьте ошибки в синтаксисе:

sudo nginx -t

Перезагрузите сервер, если ошибок нет:

sudo service nginx restart

Удаление HTTP-хедера Proxy в HAProxy

Если вы используете HAProxy для перенаправления трафика на серверы приложений, вы можете сбросить хедер Proxy перед передачей трафика.

Откройте файл /etc/haproxy/haproxy.cfg:

sudo nano /etc/haproxy/haproxy.cfg

Установите директиву http-request в разделе frontend, backend или listen.

frontend www
http-request del-header Proxy
. . .
backend web-backend
http-request del-header Proxy
. . .
listen appname 0.0.0.0:80
http-request del-header Proxy
. . .

Добавлять директиву в каждый раздел не нужно, достаточно добавить её в один. Но если вы случайно добавите директиву в каждый раздел, это никак не повредит настройке.

Сохраните и закройте файл.

Проверьте файл на наличие ошибок:

sudo haproxy -c -f /etc/haproxy/haproxy.cfg

Перезагрузите сервис:

sudo service haproxy restart

Заключение

Присутствуя в софте очень долгое время и получив широчайшее распространение, уязвимость HTTPoxy подвергает риску огромное количество приложений и библиотек. К счастью, исправить её не так уж сложно.

Tags: , , , , , ,

Добавить комментарий