21 Января, 2013

Browser Security Handbook. Глава 1, пункт 5

Сергей Сторчак

Руководство по безопасности браузеров (Browser Security Handbook). Глава 1


5.         Протокол передачи гипертекста ( HTTP )

Это протокол прикладного уровня, основанный на технологии «клиент-сервер»: клиент инициирует соединение и посылает запрос серверу, а сервер производит необходимые действия и возвращает обратно сообщение с результатом.
Первая версия протокола была разработана Тимом Бернерсом-Ли и называлась HTTP/0.9 (в настоящее время не используется браузерами, но поддерживается некоторыми серверами). HTTP/1.1- текущая версия протокола, которая описана в RFC 2616 .
Каждое HTTP-сообщение состоит из трёх частей, которые передаются в указанном порядке:
1. Стартовая строка (Startingline) — определяет тип сообщения.
2. Заголовки (Headers) — характеризуют тело сообщения, параметры передачи и прочие сведения.
3. Тело сообщения (MessageBody) — непосредственно данные сообщения.
Заголовки и тело сообщения могут отсутствовать, но стартовая строка является обязательным элементом, так как указывает на тип запроса/ответа. Исключением является версия HTTP/0.9, у которой сообщение запроса содержит только стартовую строку, а сообщения ответа - только тело сообщения.
Каждый запрос начинается с однострочного описания метода HTTP (GET- используется для запроса содержимого указанного ресурса, POST-  применяется для передачи пользовательских данных заданному ресурсу). В HTTP/1.0 и выше, за методом HTTPследует версия протокола. Ниже идут строки, содержащие разделённую двоеточием пару параметр-значение, называемые заголовками HTTP . Эти заголовки могут указывать различные мета-данные: имя хоста, информацию о клиенте, поддерживаемые типы MIME, параметры кэша, источник запроса и т. д. Заголовки должны отделяться от тела сообщения хотя бы одной пустой строкой. Тело HTTP сообщения, если оно присутствует, используется для передачи тела объекта, связанного с запросом или ответом. Присутствие тела сообщения в запросе отмечается добавлением к заголовкам запроса поля заголовка Content-Length или Transfer-Encoding.


ПримерHTTP-запроса:
POST /fuzzy_bunnies/bunny_dispenser.php HTTP/1.1

Host: www.fuzzybunnies.com

User-Agent:Bunny-Browser/1.7

Content-Type: text/plain

Content-Length:12

Referer: http://www.fuzzybunnies.com/main.html
 
HELLO SERVER
Сервер отвечает в том же порядке: код состояния,  версия протокола и заголовки, если таковые имеются:
HTTP/1.1200 OK

Server:Bunny-Server/0.9.2

Content-Type: text/plain

Connection: close

HELLO CLIENT

     Сеанс связи завершается после того, как был получен ответ на отправленный запрос. Поскольку устанавливать связь для каждого запроса неудобно, ввели дополнение к протоколу - постоянное HTTP-соединение (keep-alive connection), которое использует одно соединение для отправки и получения множественных запросов и ответов вместо открытия нового соединения для каждой пары запрос-ответ.
К сожалению, сам протокол неоднозначен и склонен к избыточности, что приводит к многочисленным проблемам и различиям между тем, как серверы, прокси-серверы, и клиенты могут интерпретировать ответы:
- Как и многие другие тексты протоколов того времени, HTTP не имел четкого определения текстового формата или формат полей. Из-за этого происходила обработка несовместимыми способами, что приводило к искажению вводимой информации, например, неверные символы новой строки (CR, LF, CR+LF, NEL ) или другие искажения управляющих символов в тексте, ошибочное количество пробелов в разделителе полей и т.д.; различные реализации Head0er: Value - может быть Head, Head: Value, Header: Value, или Head0er: Value. В RFC 2616 в разделе 19.3 “Tolerant Applications” стандарт рекомендует анализировать определенные поля и неправильные значения. Один из наиболее ярких примеров ляпа в браузере Firefox - prtime.c - функция используется для HTTP-анализа поля «Date», которая указывает на сложности при решении простой задачи.
- Плохо задан набор символов старшего бита для HTTP-заголовков, поэтому символы старшего бита разрешены в HTTP/1.0 без дальнейших ограничений, разрешены они и в HTTP/1.1 (если не закодированы в соответствии с RFC 2047 ). На практике, подобные символы  допустимы в определенных полях (Cookie, Content-Dispositionfilenames), которые не поддерживаются RFC 2047 либо поддерживаются несовместимо с другими RFC (например, требования для заголовка "Cookie"). В некоторых реализациях это приводит к преобразованию данных в UTF-8, а в других - используется однобайтовое преобразование низкоуровневыми средствами операционной системы для работы со строками.
- Поведение, когда обязательные заголовки содержат дублирующие или противоречивые запросы; приоритет появление одного и того же параметра в HTTP-заголовках у различных клиентов (например, дублирование Content-Type) или наличие противоречивых сведений (например, Content-Length не соответствует длине полезной нагрузки). В случае если приоритет может определиться, но не наглядно - например, в разделе 5.2 стандарта RFC 2616 говорится, что абсолютные запросы URI-данных имеют приоритет выше, чем хост-заголовки.
- Когда новые функции, меняющие значения запросов, были введены в стандарт  HTTP/1.1, требований по маркировке их в запросах или ответах как HTTP/1.0 не было. В результате, смысл сообщения HTTP/1.0 может значительно отличаться между действующими агентами, например, некоторыми коммерческими веб-прокси и приложениями HTTP/1.1, такими, как современные браузеры (Connection: keep-alive, Transfer-Encoding: chunked, Accept-Encoding: ...).

Ниже приводится обзор общих отличий, относящихся к безопасности, введенных в http-протокол:
Описание теста
MSIE7
MSIE8
FF3
Сафари
Опера
Хром
Android
Поддерживаются ответы без заголовков (HTTP/0.9)?
Да
Да
Да
Да
Да
Да
Да
CR (0x0D) рассматривается в качестве разделителя строки заголовка?
Да
Да
Нет
Нет
Да
Да
Нет
Значение заголовка «Content-Length»превышает фактическую длину содержимого?
Да
Да
Нет
Да
Да
Нет
Да
Имеет ли преимущество первый HTTP-заголовок с таким же именем?
Да
Да
Нет
Да
Нет
Да
Нет
Первое значение поля в HTTP-заголовке имеет приоритет?
Да
Да
Да
Да
Да
Да
Да
Заголовок «Referer» отсылается на HTTPS
^ Наверх