(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Об одной малоизвестной уязвимости в веб сайтах

Источник: habrahabr
rotor

Первое правило безопасности при разработке Веб приложений гласит: -

Не доверять данным пришедшим от клиента.
Почти все это правило хорошо знают и соблюдают. Мы пропускаем через валидаторы данные форм, кукисы, даже URI.
Но недавно я с удивлением обнаружил, что есть одна переменная, приходящая от клиента, которую почти никто не фильтрует.
Речь пойдет о компрометации веб приложения через подмену значения HTTP_HOSTи SERVER_NAME.

Если выполнить поиск по Гитхабу, по ключевому слову "HTTP_HOST", то можно найти порядка 43 страниц репозиториев, в которых используется$_SERVER['HTTP_HOST']. При беглом просмотре я обнаружил достаточно много случаев, когда данные пришедшие в этой переменной остались без фильтрации. Чаще всего проверяют только существование $_SERVER['HTTP_HOST'], но не проводят валидацию.

Опишу ситуацию для связки Nginx+php (php-fpm либо fcgi-spawn), для других веб-серверов или другого языка программирования ситуация будет отличаться в деталях, но общие принципы сохраняются.
Поведение Apache описано тут: shiflett.org/blog/2006/mar/server-name-versus-http-host

Способы компрометации


Для иллюстрации, будем использовать telnet
Заголовки, которые отправляет браузер серверу выглядят примерно так:
GET / HTTP/1.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:windows-1251,utf-8;q=0.7,*;q=0.3
Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Host:site.dev
Referer:http://site.dev/index.htm
User-Agent:TelnetTest

Если из них убрать строку (передача запроса без HTTP_HOST)
Host:site.dev,
то сервер вернет
400 Bad Request

Другой способ отправки заголовков:
GET http://site.dev/ HTTP/1.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:windows-1251,utf-8;q=0.7,*;q=0.3
Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Host:site.dev
Referer:http://site.dev/index.htm
User-Agent:TelnetTest

Результат будет точно такой же, как и при отправке первого заголовка
GET / HTTP/1.1

Но вот, если первым заголовком передать не
GET http://site.dev/ HTTP/1.1
а
GET http://site.dev/
То все последующие заголовки будут отброшены, Nginx отработает секцию server определенную для
    server_name site.dev;
Но HTTP_HOST и SERVER_NAME не будут определены.
Передать пустой HTTP_HOST не получится:
Host:
Но получится передать
Host:_
или
Host:""

Теперь самое интересное.
Подключаемся к телнету
$ telnet site.dev 80
Trying 127.0.0.1...
Connected to site.dev.
Escape character is '^]'.

Оправляем
GET http://site.dev/phpinfo.php HTTP/1.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:windows-1251,utf-8;q=0.7,*;q=0.3
Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Host:~%#$^&*()<>?@\!."'{}[]=+/
Referer:http://site.dev/index.htm
User-Agent:TelnetTest

И смотрим:
_SERVER["SERVER_NAME"]: ~%#$^&*()<>?@\!."'{}[]=+/
_SERVER["HTTP_HOST"]: ~%#$^&*()<>?@\!."'{}[]=+/

Ответ сервера:
HTTP/1.1 200 OK
Server: nginx/1.0.10
Date: Wed, 23 Jan 2013 10:31:14 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive

Если в заголовке Host: будет присутствовать '/', то сервер вернет 400 Bad Request.
Т.е. такой заголовок Host:../../ не пройдет, такой Host:http://evil.site тоже

Уязвимости


Получение доступа к приватным данным
SQL-инъекции

Способы защиты


Самый простой и доступный способ защиты (нашел тут:stackoverflow.com/questions/1459739/php-serverhttp-host-vs-serverserver-name-am-i-understanding-the-ma).
$allowed_hosts = array('foo.example.com', 'bar.example.com');
if (!isset($_SERVER['HTTP_HOST']) // !in_array($_SERVER['HTTP_HOST'], $allowed_hosts)) {
    header($_SERVER['SERVER_PROTOCOL'].' 400 Bad Request');
    exit;
}

Самый эффективный способ защиты - явно определить HTTP_HOST на стороне веб сервера.
Что бы понять, как переопределять HTTP_HOST добавим в конфиг Nginx'а такие строки:
fastcgi_param	HTTP_HOST1		$http_host;
fastcgi_param	HTTP_HOST2		$host;
fastcgi_param	HTTP_HOST3		$server_name;

Допустим у нас определены две секции server:
server {
    listen  80;
    server_name  site1.dev;
    ...
}
server {
    listen  80;
    server_name  site2.dev site3.dev;
    ...
}

Сделаем такой запрос

$ telnet site1.dev 80
Trying 127.0.0.1...
Connected to site.dev.
Escape character is '^]'.

GET http://site3.dev/phpinfo.php HTTP/1.1
Host:~%#$^&*()<>?@\!."'{}[]=+/
User-Agent:TelnetTest

На выходе получим
_SERVER["HTTP_HOST1"]: ~%#$^&*()<>?@\!."'{}[]=+/
_SERVER["HTTP_HOST2"]: site3.dev
_SERVER["HTTP_HOST3"]: site2.dev

Все логично. И наиболее корректной будет запись:
fastcgi_param	HTTP_HOST	$host;

Если сделать запрос вида
$ telnet site3.dev 80

GET /phpinfo.php HTTP/1.1
Host:~%#$^&*()<>?@\!."'{}[]=+/
User-Agent:TelnetTest

то отработает секция
server {
    listen      80 default_server;
    server_name "";
    return      444;
}

которая легко отсеет такой запрос.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 15.02.2013 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
TeeGrid VCL/FMX Source Code single license
Oracle Database Standard Edition 2 Processor License
VMware Workstation Pro 12 for Linux and Windows, ESD
FastReport VCL 6 Standard Edition Single License
Rational ClearCase Multisite Floating User License
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
СУБД Oracle "с нуля"
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
Новые материалы
Один день системного администратора
Мастерская программиста
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100