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

Maxim Dounin mdounin at mdounin.ru
Tue Jun 17 11:03:18 UTC 2014


Hello!

On Tue, Jun 17, 2014 at 01:31:16PM +0300, Gena Makhomed wrote:

> On 17.06.2014 9:30, Maxim Dounin wrote:
> 
> >>>>http://tools.ietf.org/html/rfc7230#section-5.4
> >>>>
> >>>>    A client MUST send a Host header field in all HTTP/1.1 request
> >>>>    messages.  If the target URI includes an authority component, then a
> >>>>    client MUST send a field-value for Host that is identical to that
> >>>>    authority component, excluding any userinfo subcomponent and its "@"
> >>>>    delimiter (Section 2.7.1).
> >>>>
> >>>>- это ведь требования к синтаксису, которые обязательны для выполнения.
> >>>
> >>>Нет, это не требования к синтаксису, это требования к семантике.
> >>
> >>Запись target URI в виде valid request message - это разве не syntax?
> >
> >Синтаксис - это то, что нарушает требования приведённых нормативных
> >грамматик, см. http://tools.ietf.org/html/rfc7231#section-1.2 и
> >далее.
> 
> Не все требования к синтаксису выражены в виде нормативных грамматик.
> Например, требование отправлять первой строкой запроса request-line
> - это тоже требование к синтаксису валидной HTTP request message.
> Но это требование не выражено в виде Augmented Backus-Naur Form.

http://tools.ietf.org/html/rfc7230#appendix-B

HTTP-message = start-line *( header-field CRLF ) CRLF [ message-body
    ]
status-line = HTTP-version SP status-code SP reason-phrase CRLF

> >>"SHOULD NOT" - это не запрет, а только лишь рекомендация:
> >>http://tools.ietf.org/html/rfc2119#section-4
> >>так что формально и фактически Chrome ничего не нарушает.
> >
> >Фактически - упомянутый "SHOULD NOT" на тот момент безусловно
> >отклонялся Apache'ом,
> 
> И это безусловный BUG апача, копировать его в nginx - нет смысла.
> Apache ведь не является reference implementation протокола HTTP/1.1

Это не баг - как уже говорилось выше, вернуть 400 сервер может в 
любой момент.

Это ровно такое же решение авторов апача, как и предлагаемый 
возврат 400 в случае несовпадения Host и host'а из request line.

> >а противоречащие друг другу Host +
> >Request-Line - формально вообще ничего не нарушали
> 
> Вообще-то в RFC 2616 написано в точности то же самое что и в RFC 7230:
> 
> http://tools.ietf.org/html/rfc2616#section-14.23
> 
>    The Host request-header field specifies the Internet host and port
>    number of the resource being requested, as obtained from the original
>    URI given by the user or referring resource (generally an HTTP URL,
>    as described in section 3.2.2). The Host field value MUST represent
>    the naming authority of the origin server or gateway given by the
>    original URL. This allows the origin server or gateway to
>    differentiate between internally-ambiguous URLs, such as the root "/"
>    URL of a server for multiple host names on a single IP address.
> 
> Здесь точно так же присутствует требование "MUST",
> то есть клиент, который не выполнил это требование -
> прислал на сервер невалидный запрос и сервер имеет
> полное право ответить на такой запрос статусом 400.

Здесь нет каких-либо явных требований о совпадении Host и host'а 
из request-line.

Что касается "имеет полное право", то руководствующийся RFC 2616 
сервер не имеет права ответить на такой запрос 400, так как "MUST 
ignore".  Этот вопрос, мне помнится, Валентин уже прояснял.

> >до выхода HTTPbis.
> 
> Выход HTTPbis так и не состоялся. Вместо этого - решили
> уточнить спецификацию протокола HTTP/1.1 и сконцентировать
> свои усилия в работе над протоколом HTTP/2.0 на базе SPDY,
> насколько мне известно.

HTTPbis - рабочая группа, созданная для уточнения HTTP/1.1.  И 
именно набор RFC 7230 .. 7237 - основной результат её работы, aka 
HTTPbis.

http://trac.tools.ietf.org/wg/httpbis/trac/wiki

> >И что на самом деле происходит в реальной жизни
> >- это отдельный интересный вопрос.
> 
> В реальной жизни я не встречал софта, который бы создавал запросы
> 
> GET http://apple.com/ HTTP/1.1
> Host: samsung.com
> 
> и ожидал бы, что такой запрос будет нормально обработан сервером.

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

> >Среди прочего, например, HTTPbis явно требует возвращать 400,
> >если запрос содержит несколько заголовков Host.
> 
> Нет смысла отправлять несколько одинаковых заголовков
> с одинаковым значением. А разных значений там быть не должно.
> 
> Единственное что добавилось в RFC 7230 - это более явное требование,
> чтобы такой заголовок был всего один. В RFC 2616 это было между строк.

Угу, и именно так поступал nginx до упомянутого коммита.  Только 
не работает.

Из совсем свежих примеров - Opera при работе по SPDY присылает два 
заголовка Content-Length.  Ну и кто они после этого?

> >В своё время, однако, nginx'у потребовалось от этой практики отказаться:
> >
> >http://hg.nginx.org/nginx/rev/b9de93d804ea
> >
> >Если мне не изменяет память, причина была всё та же - реальная
> >жизнь заставила.
> 
> Можно подробнее узнать про причину?

Это вопрос к Игорю, может быть он помнит подробности.  

-- 
Maxim Dounin
http://nginx.org/



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