Что такое заголовок запроса

HTTP заголовки

HTTP-сообщения (запросы и ответы) состоят из трех компонентов: стартовой строки (тип запроса или результат ответа), набора заголовков содержащих все требуемые параметры и тела (основного содержимого), причем, блок заголовков должен отделяться пустой строкой от тела.

Заголовки HTTP-сообщения позволяют указать множество дополнительной информации, которую следует знать клиенту и серверу друг о друге и передаваемых данных. HTTP-заголовков много и в этой статье будут рассмотрены только самые популярные.

Классификация HTTP-заголовков

Рассмотренная ниже классификация не единственная.

Общие заголовки

Это HTTP-заголовки, которые применяются и в HTTP-запросах клиентов и в HTTP-ответах серверов. Назначение: передача общих сведений о HTTP-сообщении.

    — настройки кеширования. — используется для обратной совместимости с кешами HTTP/1.0, т.к. заголовок для настройки кеширования (Cache-Control) появился только в HTTP/1.1. — содержит предупреждения о возможных проблемах. — определяет, остается ли сетевое соединение открытым после завершения текущей транзакции. — позволяет отправителю подсказывать, как можно использовать соединение для установки тайм-аута и максимального количества запросов. — указывает, должен ли передаваемый ресурс отображаться в строке (поведение по умолчанию без заголовка) или если он должен обрабатываться как загрузка, и браузер должен отображать диалоговое окно «Сохранить как». — добавляется прокси-серверами, как прямым, так и обратным, и может появляться в заголовках запросов и заголовках ответов. Он используется для отслеживания пересылки сообщений, избежания зацикливания запросов и определения возможностей протокола отправителей в цепочке запросов/ответов. — содержит дату и время, когда сообщение было отправлено. — позволяет клиенту переходить с HTTP 1.1 на HTTP 2.0, предполагая, что сервер решает подтвердить и реализовать поле заголовка Upgrade.

Заголовки запроса

Это HTTP-заголовки, которые применяются только в HTTP-запросах. Назначение: оповещение сервера о клиенте и о том какая информация/услуги ему нужны.

  • Authorization — содержит учетные данные для аутентификации клиента на сервере. — cодержит учетные данные для аутентификации клиента на прокси-сервере. — делает запрос условным и применяет метод, только если сохраненный ресурс соответствует одному из заданных ETag. — делает запрос условным и применяет метод, только если сохраненный ресурс не соответствует ни одному из указанных ETag. — делает запрос условным и ожидает, что объект будет передан, только если он был изменен после указанной даты. Это используется для передачи данных только тогда, когда кэш устарел. — делает запрос условным и ожидает, что объект будет передан, только если он не был изменен после указанной даты. — информирует сервер о типах данных, которые могут быть отправлены обратно. — содержит список кодировок символов которые понимает клиент. Используя согласование содержимого, сервер выбирает одну из кодировок, использует ее и сообщает клиенту о своем выборе в заголовке ответа «Content-Type», обычно в параметре «charset =…..». Браузеры в большинстве случаев не отправляют этот заголовок, поскольку значение по умолчанию для каждого ресурса, как правило, является правильным. — сообщает, какую кодировку содержимого, обычно алгоритм сжатия, может понять клиент. Используя согласование содержимого, сервер выбирает одно из предложений, использует его и информирует клиента о своем выборе с помощью заголовка ответа «Content-Encoding». — сообщает серверу о человеческом языке, который сервер должен отправить обратно. — указывает на ожидания, которые должны быть выполнены сервером для правильной обработки запроса. — содержит сохраненные файлы cookie, ранее отправленные сервером с заголовком «Set-Cookie». — используется браузерами при выдаче запроса предварительной проверки, чтобы сообщить серверу, какие HTTP-заголовки клиент может отправить при выполнении фактического запроса. — указывает, откуда происходит выборка. — выражает предпочтения отслеживания пользователя. — содержит информацию с клиентской стороны прокси-серверов, которая изменяется или теряется, когда прокси-сервер участвует в пути запроса. — содержит E-mail пользователя, который управляет запросами клиента. — указывает имя домена сервера (для виртуального хостинга) и (необязательно) номер порта TCP, который прослушивает сервер. — адрес предыдущей веб-страницы, с которой следовала ссылка на запрашиваемую в данный момент страницу. — данные клиента для идентификации (операционная система, производителя/версию ПО и т.д.). — указывает на часть документа, которую сервер должен вернуть. — создает запрос условного диапазона, который выполняется только в том случае, если данный etag или дата соответствуют удаленному ресурсу. — отправляет серверу сигнал, выражающий предпочтение клиента для зашифрованного и аутентифицированного ответа, и что он может успешно обрабатывать директиву CSP upgrade-insecure-запросы. — определяет кодировки (способы сжатия) передачи, которые клиент готов принять.

Заголовки ответа

Это HTTP-заголовки, которые применяются только в HTTP-ответах, например, «Age», «Location», «Server». Назначение: оповещение клиента о сервере и о результате обработки запроса.

  • WWW-Authenticate — определяет метод аутентификации, который должен использоваться для доступа к ресурсу. — определяет метод аутентификации, который следует использовать для получения доступа к ресурсу за прокси-сервером.
  • Age — количество секунд в течении которых объект находился в прокси-кэше. — очищает данные (куки, хранилище, кеш) связанные с запрашивающим веб-сайтом. — содержит дату и время после которых ответ считается устаревшим. — содержит дату и время последнего изменения запрошенного ресурса (чаще всего этот заголовок применяется для сайтов). — содержит идентификатор для конкретной версии ресурса. Используется для повышения эффективности кеширования. — определяет, как сопоставить заголовки запроса, чтобы решить, можно ли использовать кэшированный ответ, а не запрашивать новый с исходного сервера. — используется для отправки файлов cookie с сервера клиенту. — указывает, может ли ответ использоваться совместно с запрашивающим кодом из данного источника. — сообщает браузерам, следует ли предоставлять ответ на код JavaScript внешнего интерфейса, если включен режим учетных данных запроса (Request.credentials). — используется в ответ на запрос предварительной проверки, который включает в себя Access-Control-Request-Headers, чтобы указать, какие заголовки HTTP можно использовать во время фактического запроса. — указывает метод или методы, разрешенные при доступе к ресурсу в ответ на запрос предварительной проверки. — указывает, какие заголовки могут быть представлены как часть ответа путем перечисления их имен. — указывает, как долго могут кэшироваться результаты предварительного запроса (то есть информации, содержащейся в заголовках Access-Control-Allow-Methods и Access-Control-Allow-Headers). — указывает источники, которым разрешено просматривать значения атрибутов, извлеченных с помощью функций API Resource Timing, которые в противном случае были бы указаны как ноль из-за ограничений между источниками. — указывает состояние отслеживания, которое применено к соответствующему запросу. — указывает URL-адрес для перенаправления (редиректа) страницы. — определяет, какая информация реферера, отправленная в заголовке Реферера, должна быть включена в сделанные запросы. — это маркер, используемый сервером для объявления о поддержке частичных запросов. — указывает, где в сообщении с полным текстом содержится требуемая часть. — запрещает другим доменам читать ответ ресурсов, к которым применяется этот заголовок. — управляет ресурсами, которые клиент может загрузить для данной страницы. — позволяет сайтам принимать участие в отчете и/или обеспечивать соблюдение требований прозрачности сертификатов, что предотвращает использование неизвестных сертификатов для этого сайта незамеченным. — предоставляет механизм, позволяющий и запрещающий использование функций браузера в его собственном фрейме и в содержимом любых элементов в документе. — связывает определенный криптографический открытый ключ с определенным веб-сервером, чтобы снизить риск атак MITM с поддельными сертификатами. — отправляет отчеты о нарушении закрепления в report-uri, указанный в заголовке, но, в отличие от Public-Key-Pins, все еще позволяет браузерам подключаться к серверу, если закрепление нарушено. — позволяет веб-сайту сообщать браузерам, что доступ к нему должен осуществляться только по HTTPS, а не по HTTP. — отключает анализ MIME и заставляет браузер использовать тип, указанный в Content-Type. — указывает, что браузер (Internet Explorer) не должен отображать опцию «Открыть» файл, который был загружен из приложения, чтобы предотвратить фишинговые атаки, поскольку файл иначе получил бы доступ для выполнения в контекст приложения. — можно использовать, чтобы указать, следует ли разрешить браузеру отображать страницу в , , или .
  • X-Permitted-Cross-Domain-Policies — указывает, разрешен ли файл междоменной политики (crossdomain.xml). Файл может определять политику предоставления клиентам, таким как Adobe Flash Player, Adobe Acrobat, Microsoft Silverlight или Apache Flex, разрешения на обработку данных между доменами, которые в противном случае были бы ограничены из-за политики одного и того же происхождения.
  • X-Powered-By — информация о создателях сервера, иногда указывается хостинг-провайдером или другими средами. Обычно, не несет пользы клиенту или серверу. — это функция Internet Explorer, Chrome и Safari, которая останавливает загрузку страниц при обнаружении отраженных атак межсайтового скриптинга (XSS). — указывает форму кодирования, используемую для безопасной передачи тела полезной нагрузки пользователю. — позволяет отправителю включать дополнительные поля в конце фрагментированных сообщений, чтобы предоставлять метаданные, которые могут генерироваться динамически во время отправки тела сообщения, например, проверка целостности сообщения, цифровая подпись или статус постобработки. — определяет, что, когда у источника есть ресурсы, которые доступны через другую комбинацию протокола / хоста / порта, говорят, что у него есть доступная альтернативная служба. — сообщает браузеру, что загружаемая страница захочет выполнить большое выделение. — показывает, как долго пользовательский агент должен ждать перед выполнением последующего запроса. — сообщает одну или несколько метрик и описаний для данного цикла запрос-ответ. — связывает сгенерированный код с исходной картой, позволяя браузеру восстановить исходный источник и представить восстановленный оригинал в отладчике. — Управляет предварительной выборкой DNS — функцией, с помощью которой браузеры проактивно выполняют разрешение имен доменов для обеих ссылок, по которым пользователь может выбрать переход, а также для URL-адресов элементов, на которые ссылается документ, включая изображения, CSS, JavaScript и т. д.

Заголовки тела

Это HTTP-заголовки, которые применяются и в HTTP-запросах клиентов и в HTTP-ответах серверов. Назначение: информация о содержимом тела HTTP-сообщения.

    — размер ресурса выраженный в байтах. — указывает тип ресурсов. — используется для указания алгоритма сжатия. — используется для указания языка (языков), предназначенного для аудитории. — указывает альтернативное местоположение для возвращаемых данных. — обеспечивает возможность сериализации одной или нескольких ссылок в заголовках HTTP.

До июня 2012 года все заголовки с префиксом «X-» считались пользовательскими (нестандартными), т.е. выдуманными конкретными разработчиками для собственных нужд (так делал и я, да и сейчас делаю ). Но теперь это «правило» упразднили.

HTTP запрос

Запрос это сообщение, посылаемое клиентом серверу.
Первая строка этого сообщения включает в себя метод, который должен быть применен к запрашиваемому ресурсу, идентификатор ресурса и используемую версию протокола. Для совместимости с протоколом HTTP/0.9, существует два формата HTTP запроса:

Если HTTP/1.0 сервер получает Простой-Запрос, он должен отвечать Простым-Ответом HTTP/0.9. HTTP/1.0 клиент, способный обрабатывать Полный-Ответ, никогда не должен посылать Простой-Запрос.

Строка статуса

Строка Статуса начинается со строки с названием метода, за которым следует URI-Запроса и использующаяся версия протокола. Строка статуса заканчивается символами CRLF. Элементы строки разделяются пробелами (SP). В Строке Статуса не допускаются символы LF и CR, за исключением заключающей последовательности CRLF.

Следует отметить, что отличие Строки Статуса Полного-Запроса от Строки Статуса Простого- Запроса заключается в присутствии поля Версия-HTTP.

Метод

В поле Метод указывается метод, который должен быть применен к ресурсу, идентифицируемому URI-Запроса. Названия методов чувствительны к регистру. Существующий список методов может быть расширен.

Список методов, допускаемых отдельным ресурсом, может быть указан в поле Заголовка-Содержания «Баллов». Тем не менее, клиент всегда оповещается сервером через код статуса ответа, допускается ли применение данного метода для указанного ресурса, так как допустимость применения различных методов может динамически изменяться. Если данный метод известен серверу, но не допускается для указанного ресурса, сервер должен вернуть код статуса «405 Method Not Allowed», и код статуса «501 Not Implemented», если метод не известен или не поддерживается данным сервером. Общие методы HTTP/1.0 описываются ниже.

Метод GET служит для получения любой информации, идентифицированной URI-Запроса. Если URI- Запроса ссылается на процесс, выдающий данные, в качестве ответа будут выступать данные, сгенерированные данным процессом, а не код самого процесса (если только это не является выходными данными процесса).

Метод GET изменяется на «условный GET», если сообщение запроса включает в себя поле заголовка «If-Modified-Since». В ответ на условный GET, тело запрашиваемого ресурса передается только, если он изменялся после даты, указанной в заголовке «If-Modified-Since». Алгоритм определения этого включает в себя следующие случаи:

  • Если код статуса ответа на запрос будет отличаться от «200 OK», или дата, указанная в поле заголовка «If-Modified-Since» некорректна, ответ будет идентичен ответу на обычный запрос GET.
  • Если после указанной даты ресурс изменялся, ответ будет также идентичен ответу на обычный запрос GET.
  • Если ресурс не изменялся после указанной даты, сервер вернет код статуса «304 Not Modified».

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

Метод HEAD аналогичен методу GET, за исключением того, что в ответе сервер не возвращает Тело- Ответа. Метаинформация, содержащаяся в HTTP заголовках ответа на запрос HEAD, должна быть идентична информации HTTP заголовков ответа на запрос GET. Данный метод может использоваться для получения метаинформации о ресурсе без передачи по сети самого ресурса. Метод «Условный HEAD», аналогичный условному GET, не определен.

Метод POST используется для запроса сервера, чтобы тот принял информацию, включенную в запрос, как субординантную для ресурса, указанного в Строке Статуса в поле URI-Запроса. Метод POST был разработан, чтобы была возможность использовать один общий метод для следующих функций:

  • Аннотация существующих ресурсов;
  • Добавления сообщений в группы новостей, почтовые списки или подобные группы статей;
  • Для доставки блоков данных обрабатывающим данные процессам
  • Расширение баз данных через операцию добавления;

Реальная функция, выполняемая методом POST, определяется сервером и обычно зависит от URI- Запроса. Добавляемая информация рассматривается как субординатная указанному URI в том же смысле, как файл субординатен каталогу, в котором он находится, новая статья субординатна группе новостей, в которую она добавляется, запись субординатна базе данных.

Клиент может предложить URI для идентификации нового ресурса, включив в запрос заголовок «URI». Тем не менее, сервер должен рассматривать этот URI только как совет и может сохранить тело запроса под другим URI или вообще без него.

Если в результате обработки запроса POST был создан новый ресурс, ответ должен иметь код статуса, равный «201 Created», и содержать URI нового ресурса.

Метод PUT запрашивает сервер о сохранении Тела-Запроса под URI, равным URI-Запроса. Если URI-Запроса ссылается на уже существующий ресурс, Тело-Запроса должно рассматриваться как модифицированная версия данного ресурса. Если ресурс, на который ссылается URI-Запроса не существует, и данный URI может рассматриваться как описание для нового ресурса, сервер может создать ресурс с данным URI. Если был создан новый ресурс, сервер должен информировать направившего запрос клиента через ответ с кодом статуса «201 Created». Если существующий ресурс был модифицирован, должен быть послан ответ «200 OK», для информирования клиента об успешном завершении операции. Если ресурс с указанным URI не может быть создан или модифицирован, должно быть послано соответствующее сообщение об ошибке.

Фундаментальное различие между методами POST и PUT заключается в различном значении поля URI-Запроса. Для метода POST данный URI указывает ресурс, который будет управлять информацией, содержащейся в теле запроса, как неким придатком. Ресурс может быть обрабатывающим данные процессом, шлюзом в какой нибудь другой протокол, или отдельным ресурсом, допускающим аннотации. В противоположность этому, URI для запроса PUT идентифицирует информацию, содержащуюся в Содержании-Запроса. Использующий запрос PUT точно знает какой URI он собирается использовать, и получатель запроса не должен пытаться применить этот запрос к какому-нибудь другому ресурсу.

DELETE

Метод DELETE используется для удаления ресурсов, идентифицированных с помощью URI-Запроса. Результаты работы данного метода на сервере могут быть изменены с помощью человеческого вмешательства (или каким-нибудь другим способом). В принципе, клиент никогда не может быть уверен, что операция удаления была выполнена, даже если код статуса, переданный сервером, информирует об успешном выполнении действия. Тем не менее, сервер не должен информировать об успехе до тех пор, пока на момент ответа он не будет собираться стереть данный ресурс или переместить его в некоторую недостижимую область.

Метод LINK устанавливает взаимосвязи между существующим ресурсом, указанным в URI-Запроса, и другими существующими ресурсами. Отличие метода LINK от остальных методов, допускающих установление ссылок между документами, заключается в том, что метод LINK не позволяет передавать в запросе Тела-Запроса, и том, что в результате работы данного метода не создаются новые ресурсы.

UNLINK

Метод UNLINK удаляет одну или более ссылочных взаимосвязей для ресурса, указанного в URI- Запроса. Эти взаимосвязи могут быть установлены с помощью метода LINK или какого-нибудь другого метода, поддерживающего заголовок «Link». Удаление ссылки на ресурс не означает, что ресурс прекращает существование или становится недоступным для будущих ссылок.

Поля Заголовка-Запроса

Поля Заголовка-Запроса позволяют клиенту передавать серверу дополнительную информацию о запросе и о самом клиенте.

Кроме того через механизм расширения могут быть определены дополнительные заголовки; приложения, которые их не распознают, должны трактовать эти заголовки, как Заголовки-Содержания.

Ниже будут рассмотрены некоторые из Заголовков-Запроса.

В случае присутствия поля From, оно должно содержать полный E-mail адрес пользователя, который управляет программой-агентом, осуществляющей запросы. Этот адрес должен быть задан в формате, определенном в RFC 822. Формат данного поля следующий: From = «From» «:» спецификация адреса. Например:

From: webmaster@WWW.org

Данное поле может быть использовано для функций захода в систему, а также для идентификации источника некорректных или нежелательных запросов. Оно не должно использоваться, как несекретная форма разграничения прав доступа. Интерпретация этого поля состоит в том, что обрабатываемый запрос производится от имени данного пользователя, который принимает ответственность за применяемый метод. В частности, агенты-роботы должны использовать этот заголовок для того, чтобы можно было связаться с тем человеком, который отвечает за работу робота, в случае возникновения проблем. Почтовый Internet адрес, указывающийся в этом поле, не обязан соответствовать адресу того хоста, с которого был послан данный запрос. По возможности, адрес должен быть доступным Internet адресом вне зависимости от того, является ли он в действительности Internet E-mail адресом или Internet E-mail представлением адреса других почтовых систем.

Замечание: Клиент не должен использовать поле заголовка From без позволения пользователя, так как это может войти в конфликт с его частными интересами или с местной, используемой им, системой безопасности. Настоятельно рекомендуется предоставление пользователю возможности запретить, разрешить или модифицировать это поле в любой момент перед запросом.

If-Modified-Since

Поле заголовка If-Modified-Since используется с методом GET для того, чтобы сделать его условным: если запрашиваемый ресурс не изменялся со времени, указанного в этом поле, копия этого ресурса не будет возвращена сервером; вместо этого, будет возвращен ответ «304 Not Modified», несодержащий Тела- Ответа.

Пример использования заголовка:

If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT

Целью этой особенности является предоставление возможности эффективного обновления информации локальных кэшей с минимумом передаваемой информации. Тот же результат может быть достигнут применением метода HEAD с последующим использованием GET, если сервер указал, что содержимое документа изменилось.

User-Agent

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

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

Строка, описывающая название продукта, должна быть короткой и давать информацию по существу — использование данного заголовка для рекламирования какой-либо другой, не относящейся к делу, информации не допускается и рассматривается, как не соответствующее протоколу. Хотя в поле версии продукта может присутствовать любая строка, данная строка должна использоваться только для указания версии продукта. Поле User-Agent может включать в себя дополнительную информацию в комментариях, которые не являются частью его значения.

Комментарии и пожелания присылайте по адресу : webmaster@genesis.ricor.ru
Copyright ╘ 1998 Gensis Net. All rights reserved.

Часть 3. Протоколы HTTP/HTTPS

Так называют общепринятое соглашение, благодаря которому разработчики разных сервисов отправляют информацию в едином виде. Например, используя Google Chrome, ты можешь получить информацию и с Facebook, и с Twitter, потому что разработчики передают ее с помощью стандартного протокола HTTP, а твой браузер умеет его обрабатывать. Единые правила очень удобны и самим разработчикам серверных частей: существует очень много библиотек, которые могут за тебя преобразовать информацию и отправить по необходимому протоколу. Изначально HTTP задумывался как протокол передачи HTML-страниц. Долгое время так и было, но сейчас программисты частенько передают по нему и строки, и медиафайлы. В общем, этот протокол универсальный и гибкий, и использовать его действительно просто. А как это делать — сейчас разберемся.

Структура HTTP

  1. Стартовая строка (Starting line) — определяет служебные данные.
  2. Заголовки (Headers) — описание параметров сообщения.
  3. Тело сообщения (Body) — данные сообщения. Должны отделяться от заголовков пустой строкой.

Как выглядит простой HTTP-запрос

  • GET — метод запроса;
  • / — путь запроса (path);
  • HTTP/1.1 — версия протокола передачи данных.
  • Host — хост, которому адресован запрос;
  • User-Agent — клиент, который отправляет запрос.

HTTP-ответы

После получения запроса, сервер его обрабатывает и отправляет ответ клиенту: Стартовая строка в респонсе содержит версию протокола (HTTP/1.1), Код статуса (200), Описание статуса (OK). В заголовках — тип и длина контента. В теле ответа — HTML-код, который браузер прорисует в HTML-страницу.

Response Status Codes

  • 1xx — информационный. Запрос получен, сервер готов к продолжению;
  • 2xx — успешный. Запрос получен, понятен и обработан;
  • 3xx — перенаправление. Следующие действия нужно выполнить для обработки запроса;
  • 4xx — ошибка клиента. Запрос содержит ошибки или не отвечает протоколу;
  • 5xx — ошибка сервера. Сервер не смог обработать запрос, хотя был составлен верно;
  • 200 OK — реквест получен и успешно обработан;
  • 201 Created — реквест получен и успешно обработан, в результате чего создан новый ресурс или его экземпляр;
  • 301 Moved Permanently — запрашиваемый ресурс был перемещен навсегда, и последующие запросы к нему должны происходить по новому адресу;
  • 307 Temporary Redirect — ресурс перемещен временно. Пока к нему можно обращаться, используя автоматическую переадресацию;
  • 403 Forbidden — запрос понятен, но нужна авторизация;
  • 404 Not Found — сервер не нашел ресурс по этому адресу;
  • 501 Not Implemented — сервер не поддерживает функциональность для ответа на этот запрос;
  • 505 HTTP Version Not Supported — сервер не поддерживает указанную версию HTTP-протокола.

В чем отличие между HTTPS и HTTP

HTTPS синтаксически идентичен протоколу HTTP, то есть использует те же стартовые строки и заголовки. Единственные отличия — дополнительное шифрование и порт по умолчанию (443) . HTTPS шифруется между HTTP и TCP, то есть между прикладным и транспортным уровнями. Если забыл, что это такое, загляни в статью о модели OSI. Современный стандарт шифрования — по протоколу TLS. В эту темы мы слишком углубляться не будем, но запомни, что шифрование происходит перед тем, как информация попадает на транспортный уровень . В HTTPS шифруется абсолютно вся информация, кроме хоста и порта, куда отправлен запрос. Для перевода сервера на использование HTTPS протокола вместо HTTP, нам не нужно менять код сервера. Включение этой фичи происходит в контейнерах сервлетов, о которых мы поговорим в следующих статьях. А на сегодня все. Впрочем, погоди. Чтобы пощупать HTTP-запросы, открой Google Chrome, нажми F12, выбери вкладку Network. Тут будут отображаться все реквесты и респонсы, отправленные/полученные твоим браузером. Часть 4.Основы Maven Часть 5. Сервлеты. Пишем простое веб-приложение Часть 6. Контейнеры сервлетов Часть 7. Знакомство с паттерном MVC (Model-View-Controller) Часть 8. Пишем небольшое приложение на spring-boot

HTTP — заголовки

При обращении к этой странице ваш браузер отправил следующие http-заголовки:

Host: htmlweb.ru
X-Forwarded-Proto: https
X-Forwarded-Port: 443
Connection: close
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Referer: https://htmlweb.ru/

Заголовки отправляемые сервером

В соответствии со спецификацией http, этот протокол также поддерживает передачу служебной информации от сервера к браузеру, оформленной в виде специальных заголовков.

Таким образом, http headers — это средство общения сервера с удаленным клиентом. Каждый заголовок обычно состоит из одиночной линии ascii текста с именем и значением. Сами заголовки никак не отображаются в окне броузера, но зачастую могут сильно изменить отображение сопутствующего документа.

Механизм отправки http заголовков в php.
Механизм отправки заголовков в php представлен функцией header(). Особенность протокола http заключается в том, что заголовок должен быть отправлен до посылки других данных, поэтому функция должна быть вызвана в самом начале документа и должна выглядеть следующим образом:

header(«http заголовок»[, replace]);

Необязательный параметр replace может принимать значения (true или false) и указывает на то, должен ли быть заменен предыдущий заголовок подобного типа, либо добавить данный заголовок к уже существующему.

В отношении функции header() часто применяется функция headers_sent(), которая в качестве результата возвращает true в случае успешной отправки заголовка и false в обратном случае.

Рассмотрим наиболее используемые http заголовки.

Cache-control

Заголовок управления кешированием страниц. Вообще, данная функция является одной из самых распространенных в использовании заголовков.

    Данный заголовок может быть использован со следующими значениями:
  • no-cache — Запрет кеширования. Используется в часто обновляемых страницах и страницах с динамическим содержанием. Его действие подобно meta тегу «pragma: no-cache».
  • public — Разрешение кеширования страницы как локальным клиентом, так и прокси-сервером.
  • private — Разрешение кеширования только локальным клиентом.
  • max-age — Разрешение использования кешированного документа в течение заданного времени в секундах.
  • no-store — Cтраница содержит приватные данные, сохранять в кэше нельзя!

Совсем жесткий запрет кеширования на всех этапах:

Expires

Устанавливает дату и время, после которого документ считается устаревшим. Дата должна указываться в следующем формате (на английском языке):

День недели (сокр.) число (2 цифры) Месяц (сокр.) год часы:минуты:секунды gmt

Например, fri, 09 jan 2002 12:00:00 gmt

Текущее время в этом формате возвращает функция gmdate() в следующем виде:

Возможно использование данного http заголовка для запрета кеширования. Для этого необходимо указать прошедшую дату. Иногда можно встретить и такую комбинацию Expires: now

Last-modified

Указывает дату последнего изменения документа. Дата должна задаваться в том же формате, что и в случае с заголовком expires. Данный заголовок можно не использовать для динамических страниц, так как многие серверы (например, apache) для таких страниц сами выставляют дату модификации.

При запросе это значение передаётся клиентом в специальном заголовке запроса: If-Modified-Since. Обработчик запроса может проверить, изменился ли объект, и если нет — вернуть ответ с пустым телом и кодом ответа 304 Not Modified. Само содержимое страницы не передаётся, и клиент будет использовать то содержимое, которое хранится у него в кэше.

Возможно сделать страницу всегда обновленной:

ETag’и (Entity Tags — тэги сущностей) — механизм, который используют браузеры и веб-сервера, чтобы определить, является ли объект, находящийся в кэше браузера таким же, как соответствующий объект на сервере (а Entity (сущность) — другое название того, что мы называем компонентами: картинки, скрипты и т.д.). Тэги сущностей были задуманы как механизм для определения актуальности сущности в кэше браузера, что является более гибким подходом, нежели проверка по дате последнего изменения (last-modified). ETag — это строка, которая однозначно идентифицирует конкретную версию компонента. Единственное требование: строка должна быть заключена в двойные кавычки. Сервер указывает ETag для компонента используя HTTP-заголовок ETag:

Позднее, если браузер хочет определить актуальность компонента, он передает заголовок If-None-Match для передачи ETag’а обратно на сервер. Если ETag’и совпадают, ответ от сервера приходит со статус-кодом 304, уменьшая таким образом объем передачи на 12195 байт:

Включить ETag для Apache можно, например, следующей директивой:

Открючить ETag для Apache:

Location

Полезный заголовок, который перенаправляет броузер на указанный адрес. Его действие сравнимо с meta тегом refresh:

Например, этот заголовок может быть использован так:

Content-type
Content-length
Status

Status : MIME тип возвращаемого документа Эта директива используется для задания серверу HTTP/1.0 строки-статус, которая будет послана клиенту. Формат: nnn xxxxx, где nnn — 3-х цифровой статус-код, и xxxxx строка причины, например: «Forbidden» (Запрещено). Http-коды статусов.

Content-Encoding

Content-Encoding : gzip Способность принимать сжатое содержимое клиент отправляет серверу с помощью заголовка Accept-Encoding: gzip. Обычно сервер указывает Accept-Encoding: gzip,deflate.

Range
Разрешить кросс-доменные запросы

При использовании .htaccess: Подробнее см. http://www.w3.org/TR/cors/#access-control-allow-origin-response-hea

X-XSS-Protection

Атака XSS (межсайтовый скриптинг) это тип атаки, при котором вредоносный код может быть внедрён в атакуемую страницу.

Например вот так:

Такой тип атаки легко обнаружить и браузер вполне может с этим справиться: если в исходном коде содержится часть запроса, то это может оказаться угрозой.

И заголовок X-XSS-Protection управляет этим поведением браузера.

  • 0 фильтр выключен
  • 1 фильтр включен. Если атака обнаружена, то браузер удалит вредоносный код.
  • 1; mode=block. Фильтр включен, но если атака обнаружится, страница не будет загружена браузером.
  • 1; report=http://domain/url. фильтр включен и браузер очистит страницу от вредоносного кода, при этом сообщив о попытке атаки. Тут используется функция Chromium для отправки отчёта о нарушении политика защиты контента (CSP) на определённый адрес.

Буду использовать Google Chrome 55.

Без заголовка

Ничего не произойдёт, браузер успешно заблокирует атаку. Chrome, по умолчанию, блокирует угрозу и сообщает об этом в консоли.

X-XSS-Protection: 0
X-XSS-Protection: 1

Страница была очищена из-за явного указания заголовка.

X-XSS-Protection: 1; mode=block

В этом случае атака будет предотвращена путём блокирования загрузки страницы.

X-XSS-Protection: 1; report=http://localhost:1234/report

Атака предотвращена и сообщение об этом отправлено по соответствующему адресу.

X-Frame-Options

При помощи данного заголовка можно защититься от так называемого Кликджекинга [Clickjacking].

Представьте, что у злоумышленника есть канал на YouTube и ему хочется больше подписчиков.

Он может создать страницу с кнопкой «Не нажимать», что будет значить, что все на неё обязательно нажмут. Но поверх кнопки находится абсолютно прозрачный iframe и в этом фрейме прячется страница канала с кнопкой подписки. Поэтому при нажатии на кнопку, на самом деле пользователь подписывается на канал, если конечно, он был залогинен в YouTube.

Сперва нужно установить расширение для игнорирования данного заголовка.

Создадим простую страницу.

Как можно заметить, я разместил фрейм с подпиской прям над кнопкой (z-index: 1) и поэтому если попытаться на неё нажать, то на самом деле нажмётся фрейм. В этом примере фрейм не полностью прозрачен, но это исправляется значением opacity: 0.

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

Для предотвращения страницы быть использованной во фрейме нужно использовать заголовок X-Frame-Options.

  • deny не загружать страницу вообще.
  • sameorigin не загружать, если источник не совпадает.
  • allow-from: ДОМЕН можно указать домен, с которого страница может быть загружена во фрейме.
Без заголовка

Все смогут встроить наш сайт по адресу localhost:1234 во фрейм.

X-Frame-Options: deny

Страницу вообще нельзя использовать во фрейме.

X-Frame-Options: sameorigin

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

X-Frame-Options: allow-from localhost:4321

Похоже, что Chrome игнорирует такую опцию, т.к. существует заголовок Content-Security-Policy (о ней будет рассказано ниже). Не работает это и в Microsoft Edge.

X-Content-Type-Options

Данный заголовок предотвращает атаки с подменой типов MIME ( ) или несанкционированного хотлинка ()

Без заголовка

Хоть script.txt и является текстовым файлом с типом text/plain, он будет запущен как скрипт.

X-Content-Type-Options: nosniff

На этот раз типы не совпадают и файл не будет исполнен.

Content-Security-Policy

Это относительно молодой заголовок и помогает уменьшить риски атаки XSS в современных браузерах путём указания в заголовке какие именно ресурсы могут подргружаться на странице.

Например, можно попросить браузер не исполнять inline-скрпиты и загружать файлы только с одного домена. Inline-скрпиты могут выглядеть не только как , но и как .

Посмотрим как это работает.

Без заголовка

Это работает так, как вы и ожидали

Content-Security-Policy: default-src ‘none’

default-src применяет правило для всех ресурсов (картинки, скрипты, фреймы и т.д.), значение ‘none’ блокирует всё. Ниже продемонстрировано что происходит и ошибки, показываемые в браузере.

Chrome отказался запускать любые скрипты. В таком случае не получится даже загрузить favicon.ico.

Content-Security-Policy: default-src ‘self’

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

Content-Security-Policy: default-src ‘self’; script-src ‘self’ ‘unsafe-inline’

На этот раз мы разрешили исполнение и inline-скриптов. Обратите внимание, что XSS атака в запросе тоже была заблокирована. Но этого не произойдёт, если одновременно поставить и unsafe-inline, и X-XSS-Protection: 0.

Другие значения

На сайте content-security-policy.com красиво показаны множество примеров.

  • default-src ‘self’ разрешит ресурсы только с одного источника
  • script-src ‘self’ www.google-analytics.com ajax.googleapis.com разрешит Google Analytics, Google AJAX CDN и ресурсы с одного источника.
  • default-src ‘none’; script-src ‘self’; connect-src ‘self’; img-src ‘self’; style-src ‘self’; разрешит изображения, скрипты, AJAX и CSS с одного источника и запретит загрузгу любых других ресурсов. Для большинства сайтов это хорошая начальная настройка.

Я этого не проверял, но я думаю, что следующие заголовки эквиваленты:

  • frame-ancestors ‘none’ и X-Frame-Options: deny
  • frame-ancestors ‘self’ и X-Frame-Options: sameorigin
  • frame-ancestors localhost:4321 и X-Frame-Options: allow-from localhost:4321
  • script-src ‘self’ без ‘unsafe-inline’ и X-XSS-Protection: 1

Если взглянуть на заголовки facebook.com или twitter.com, то можно заметить, что эти сайты используют много CSP.

Strict-Transport-Security

HTTP Strict Transport Security (HSTS) это механизм политики безопасности, который позволяет защитить сайт от попытки небезопасного соединения.

Допустим, что мы хотим подключиться к facebook.com. Если не набрать перед запросом https://, то протокол, по умолчанию, будет выбран HTTP и поэтому запрос будет выглядеть как http://facebook.com.

После этого мы будем перенаправлены на защищённую версию Facebook.

Если подключиться к публичной WiFi точке, которая принадлежит злоумышленнику, то запрос может быть перехвачен и вместо facebook.com злоумышленник может подставить похожую страницу, чтобы узнать логин и пароль.

Чтобы обезопаситься от такой атаки, можно использовать вышеупомянутый заголовок, который скажет клиенту в следующий раз использовать https-версию сайта.

Если пользователь был залогинен в Facebook дома, а потом попытался открыть его из небезопасной точки доступа, то ему ничего не угрожает, т.к. браузеры запоминают этот заголовок.

Но что будет, если подключиться в небезопасной сети первый раз? В этом случае защититься не получится.

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

Можно отправить свой домен по этому адресу. Там также можно узнать правильно ли используется заголовок.

  • max-age=15552000 время, в секундах, которое браузер должен помнить о заголовке.
  • includeSubDomains Если указать это опциональное значение, то заголовок распространяется и на все поддомены.
  • preload если владелец сайта хочет, чтобы домен попал в предопределённый список, поддерживаемый Chrome (и используемый Firefox и Safari).

А если потребуется переключиться на HTTP перед сроком истечения max-age или если установлен preload? Можно поставить значение max-age=0 и тогда правило перехода на https версию работать перестанет.

Public-Key-Pins

HTTP Public Key Pinning (HPKP) это механизм политики безопасности, который позволяет HTTPS сайтам защититься от использования злоумышленниками поддельных или обманных сертификатов.

  • pin-sha256=»» в кавычках находится закодированный с помощью Base64 отпечаток Subject Public Key Information (SPKI). Можно указать несколько пинов для различных открытых ключей. Некоторые браузеры в будущем могут использовать и другие алгоритмы хеширования, помимо SHA-256.
  • max-age= время, в секундах, которое браузер запоминает что для доступа к сайту нужно использовать только перечисленные ключи.
  • includeSubDomains если указать этот необязательный параметр, то заголовок действует и на все поддомены.
  • report-uri=»» если указать URL, то при ошибке проверки ключа, соответствующее сообщение отправится по указанному адресу.

Вместо заголовка Public-Key-Pins можно использовать Public-Key-Pins-Report-Only, в таком случае будут отправляться только сообщения об ошибках совпадения ключей, но браузер всё равно будет загружать страницу.

Так делает Facebook:

Зачем это нужно? Не достаточно ли доверенных центров сертификации (CA)?

Злоумышленник может создать свой сертификат для facebook.com и путём обмана заставить пользователя добавить его в своё хранилище доверенных сертификатов, либо он может быть администратором.

Попробуем создать сертификат для facebook.

И сделать его доверенным в локальной системе.

А теперь запустим веб сервер, использующий этот сертификат.

Переключимся на сервер

Посмотрим что получилось

Отлично. curl подтверждает сертификат.

Так как я уже заходил на Facebook и Google Chrome видел его заголовки, то он должен сообщить об атаке но разрешить страницу, так?

Неа. Ключи не проверялись из-за локального корневого сертификата [Public-key pinning bypassed]. Это интересно…

Тот же результат. Думаю это фича.

Но в любом случае, если не добавлять эти сертификаты в локальное хранилище, открыть сайты не получится, потому что опции продолжить небезопасное соединение в Chrome или добавить исключение в Firefox не будет.

Content-Encoding: br

Данные сжаты при помощи Brotli.

Алгоритм обещает лучшее сжатие чем gzip и сравнимую скорость разархивирования. Поддерживается Google Chrome.

Разумеется, для него есть модуль в node.js.

Исходный размер: 700 Кб
Brotli: 204 Кб
Gzip: 241 Кб

Timing-Allow-Origin

С помощью Resource Timing API можно узнать сколько времени заняла обработка ресурсов на странице.

Поскольку информация о времени загрузки может быть использована чтобы определить посещал ли пользователь страницу до этого (обращая внимание на то, что ресурсы могут кэшироваться), стандарт считается уязвимым, если давать такую информацию любым хостам.

Похоже, если не указать Timing-Allow-Origin, то получить детальную информацию о времени операций (поиска домена, например) можно только для ресурсов с одним источником.

Использовать можно так:

  • Timing-Allow-Origin: *
  • Timing-Allow-Origin: http://foo.com http://bar.com
Alt-Svc

Альтернативные Сервисы [Alternative Services] позволяют ресурсам находиться в различных частях сети и доступ к ним можно получить с помощью разных конфигураций протокола.

Такой используется в Google:

  • alt-svc: quic=»:443″; ma=2592000; v=«36,35,34»

Это означает, что браузер, если захочет, может использовать QUIC, это HTTP над UDP, через порт 443 следующие 30 дней (ma = 2592000 секунд, или 720 часов, т.е 30 дней). Понятия не имею что означает параметр v, версия?

Ниже несколько P3P заголовков, которые я встречал:

  • P3P: CP=«This is not a P3P policy! See support.google.com/accounts/answer/151657?hl=en for more info.»
  • P3P: CP=«Facebook does not have a P3P policy. Learn why here: fb.me/p3p»

Некоторые браузеры требуют, чтобы cookies третьих лиц поддерживали протокол P3P для обозначения мер конфиденциальности.

Организация, основавшая P3P, Консорциум Всемирной паутины (W3C), приостановила работу над протоколом несколько лет назад из-за того, что современные браузеры не до конца поддерживают протокол. В результате, P3P устарел и не включает в себя технологии, которые сейчас используются в сети, поэтому большинство сайтов не поддерживают P3P.

Я не стал слишком углубляться, но видимо заголовок нужен для IE8 чтобы принимать cookies третьих лиц.

Например, если в IE настройка приватности высокая, то все cookies с сайтов, у которых нет компактной политики конфиденциальности, будут блокированы, но те у которых есть заголовки похожие на вышеупомянутые, заблокированы не будут.

Протокол HTTP

Все HTTP-транзакции имеют один общий формат. Каждый запрос клиента и ответ сервера состоит из строки запроса (ответа), сопровождаемой вспомогательными строками заголовка и тела. Строки заголовка отделяются друг от друга парой символов . Тело отделяется от заголовков пустой строкой. Заголовки могут быть любой длины, и сервер обязан либо обработать длинный заголовок, либо выдать соответствующий код ошибки. Тело запроса (ответа) представляет последовательность байтов, на которую не накладывается никаких ограничений.

Клиент устанавливает связь с сервером по назначенному номеру порта (по умолчанию — 80)., и, не дожидаясь никакой реакции от сервера, посылает запрос, указав HTTP-команду, называемую методом, адрес документа и номер версии HTTP. Например:

В примере используется метод GET, которым с помощью версии 1.0 HTTP запрашивается документ index.html с виртуального сервера www.example.com.

Послав запрос и заголовки, клиент может отправить дополнительные данные. Эти данные используются главным с методом POST для передачи .

Сервер отвечает на запрос клиента следующим образом:

Первая часть строка ответа сервера — строка состояния, содержащая три поля: версию HTTP, числовой код ответа и текстовое описание этого кода.

После заголовка отправляются затребованные данные. Если запрос клиента удовлетворить нельзя, передается сообщение об ошибке в приемлемом для чтения человеком виде.

HTTP не сохраняет информацию по транзакциям, каждая пара запрос-ответ проводится независимо, даже в рамках одного TCP соединения.

Методы

Метод — это HTTP-команда, с которой начинается первая строка запроса клиента.Реально используются GET, HEAD и POST. При задании имен методов учитывается регистр, поэтому GET и get различаются.

Приведенные ниже методы определены, но практически не используются:

Метод GET

GET — это запрос к серверу, который ничего не изменяет на сервере, например, выполняет считывание записи из БД.

В URL кодируются параметры запроса. Сначала идут позиционные параметры, разделенные знаком ‘/’, а затем, после символа ‘&’ — именованные в виде пар ключ-значение. Пары отделяются друг от друга амперсандом ‘&’. Например:

Максимальная длина строки параметров при реализации может быть ограничена как со стороны клиента, так и со стороны сервера.

Хотя позиционные параметры могут выглядеть, как имена каталогов и файлов, реальная интерпретация зависит от реализации на стороне сервера. Например, следующая запись может означать запуск скрипта /cgi-bin/display.pl для вывода файла /text/doc.txt (а может и не означать):

Метод POST

Метод POST это запрос к серверу, который изменяет состояние сервера, например вносит запись в БД.

Параметры запроса в методе POST могут передаваться в теле запроса. В этом случае их общая длина ничем не ограничена.

Метод HEAD

Метод HEAD аналогичен методу GET, за исключением того, что сервер ничего не посылает в информационной части ответа. Метод HEAD запрашивает только информацию заголовка о файле или ресурсе. Этот метод используется, когда клиент хочет получить информацию о документе, не получая его. Например, клиента может интересовать:

  • время изменения документа;
  • размер документа;
  • тип документа;
  • тип сервера.

Некоторые заголовки не являются обязательными и могут отсутствовать в ответе сервера.

Авторизация

Если ресурс требует авторизации пользователя, то сервер в ответ на запрос может вернуть код ответа 401 Unauthorized и строку заголовка с указанием области доступа для которой требуется авторизация

В реальной жизни используется тип авторизации Basic и NTLM.

Заголовки запроса

В запросе клиент должен передать URI запрашиваемого документа. Это может быть сделано в абсолютной или относительной форме. В первом случае в состав URI должны входить название протокола и имя сервера.

Во втором случае передается только путь к документу.

В этом случае имя и порт хоста, может быть передано в строке заголовка Host:

Наличие имени хоста необходимо для обращений к прокси-серверу, или для обращения к одному из виртуальных хостов размещенных на одном сервере. Если хост, заданный одним из двух способов, не существует, то сервер возвращает ответ 400- Bad Request.

Поля заголовка запроса позволяют клиенту передавать серверу дополнительную информацию о запросе и о самом клиенте.

Передача данных в ответе сервера

Несколько заголовков используемых в ответе сервера, позволяют точно описать формат и размер передаваемых данных.

Content-Type: Тип сообщения, аналогичен типу содержимого в стандарте MIME и указывается в формате тип/подтип.

Серверы используют типы сообщения в заголовках Content-Type, чтобы сообщить клиенту о том, в каком формате передается прилагаемое содержимое

В типе сообщения для текстовых форматов может быть указана использованная кодировка.

Content-Encoding: Для 8 битового протокола HTTP, данный заголовок означает, что данные дополнительно закодированы, например сжаты. Определены три типа кодирования gzip, compress, deflate, что соответствует форматам программ gzip, compress и библиотеки zlib. Например:

Большое значение в реализации протокола HTTP имеет уведомление клиента о размере данных в теле ответа, т.к. в силу 8 битовости протокола тело ответа не может сопровождаться каким либо ограничителем.

Content-Length: Длина тела сообщения. В протоколе HTTP/1.0 это была единственная возможность передать клиенту информацию о размере данных.

Кодирование данных кусками (chunced) было введено в HTTP/1.1. В заголовках ответа должна присутствовать строка

А тело сообщения строится по следующим правилам

Признаком завершения передачи является кусок нулевой длины.

Следует отметить, что символы в конце куска, не являются его частью. Подобное кодирование очень удобно в тех случаях, когда размер данных заранее неизвестен, и достаточно велик.

Еще одной возможностью для кодирования данных является использование для тела сообщения типа multipart/bytranges – эквивалентного MIME multipart/*

Если размер сообщения не указан, не используется кодирование кусками и тип тела сообщения не multipart/bytranges, то клиент определяет конец тела ответа по закрытию TCP соединения.

Что такое заголовок запроса

HTTP ( HyperText Transfer Protocol — «протокол передачи гипертекста ») — протокол прикладного уровня передачи данных. Основой HTTP является технология «клиент-сервер» , то есть предполагается существование потребителей ( клиентов ), которые инициируют соединение и посылают запрос , и поставщиков ( серверов ), которые ожидают соединения для получения запроса, производят необходимые действия и возвращают обратно сообщение с результатом (ответом).

Заголовки HTTP (англ. HTTP Headers ) — это строки в HTTP-сообщении, содержащие разделённую двоеточием пару имя-значение. Формат заголовков соответствует общему формату заголовков текстовых сетевых сообщений ARPA (см. RFC 822). Заголовки должны отделяться от тела сообщения хотя бы одной пустой строкой.

Все заголовки разделяются на четыре основных группы:

  1. General Headers (рус. Основные заголовки ) — должны включаться в любое сообщение клиента и сервера.
  2. Request Headers (рус. Заголовки запроса ) — используются только в запросах клиента.
  3. Response Headers (рус. Заголовки ответа ) — только для ответов от сервера.
  4. Entity Headers (рус. Заголовки сущности ) — сопровождают каждую сущность сообщения.

Заголовки в HTML

Язык разметки HTML позволяет задавать необходимые значения заголовков HTTP внутри с помощью тега . При этом название заголовка указывается в атрибуте http-equiv, а значение — в content. Почти всегда выставляется значение заголовка Content-Type с указанием кодировки, чтобы избежать проблем с отображением текста браузером.

Статус-коды:

CGI (от англ. Common Gateway Interface — «общий интерфейс шлюза») — стандарт интерфейса, используемого для связи внешней программы с веб-сервером. Программу, которая работает по такому интерфейсу совместно с веб-сервером, принято называть шлюзом, хотя многие предпочитают названия «скрипт» (сценарий) или «CGI-программа».

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

Переменные окружения (http://www.php.su/learnphp/cgi/?cgivars)
Переменная AUTH_TYPE

Скрипты CGI используют переменную окружения AUTH_TYPE для идентификации пользователя, который пытается получить доступ к скрипту. Если сервер сконфигурирован так, чтобы поддерживать идентификацию пользователя, то пользователь, пытающийся получить доступ к скрипту, должен назвать свое имя и пароль. Например, следующее значение переменной означет, что от пользователя требуется основной уровень идентификации:

Переменная CONTENT_LENGTH

Скрипты используют переменную окружения CONTENT_LENGTH для того, чтобы определить точное число байт, содержащихся в просоединенных данных. Например, если запрос содержит документ длиной в 1,024 байта, то переменной окружения присваивается следующее значение:

Переменная CONTENT_TYPE

Скрипты используют эту переменную окружения для запросов, которые содержат присоединенную информацию. К такому типу запросов отоносится HTTP-операция POST. Содержащаяся в переменной информация указывает на тип присоединенных данных ( MIME-тип.подтип). Например, если запрос содержит присоединенный документ HTML , то переменная окружения будет принимать следующие значения:

Переменная GATEWAY_INTERFACE

Скрипты используют эту переменную для того, чтобы определить версию, номер выпуска спецификации CGI, которой удовлетворяет Web-сервер. Формат номера выпуска спецификации следующий: CGI/номер выпуска. Например, для CGI выпуска 1.1 переменная окружения будет иметь следующий вид:

Переменная PATH_INFO

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

Путь записывается в относительной форме, где за базу берется корневой каталог сервера. Иными словами, корневой каталог сервера является базисом для относительного пути, который и присваивается переменной PATH_INFO. Например, если задан путь c:/cgi-bin/example1.exe/sports.html, то переменная окружения будет иметь следующий вид:

Переменная PATH_TRANSLATED

Скрипты используют эту переменную для получения окончательной, пригодной для непосредственного использования информации относительно пути. Сервер переводит информацию переменной путем выполнения необходимых преобразований пути. Например, если переменная PATH_TRANSLATED имеет значение /sports.html, а корневым дирикторием сервера служит c:,то переменная окружения будет иметь следующее значение:

Переменная QUERY_STIRNG

Скрипты используют эту переменную для того, чтобы получить информацию в текстовой форме ( состоящую из аргументов ), которая следует справа от знака вопроса после URL, переданного от пользователя скрипту для обработки. Эта текстовая сторока содежит вход для скрипта. Далее сервер заменяет в данном тексте каждый пробел на знак " + ", а все непечатные символы знаком " %dd", где d является базой десятичной системы счисления.

Скрипт должен содержать код для расшифровки этой текстовой строки. Сервер, передавая эту информацию скрипту, не должен заниматься декодированием информации запроса каким-либо образом. Сервер должен также установить переменную QUERY_STRING в случае, если пользователь обеспечивает какую-то информацию запроса. Например, для URL http://www.jamsa.com/cgi-bin/grandma.exe?name=margaret+alarcon переменная окружения имеет значением следующую величину:

Переменная REMOTE_ADDR

Скрипты используют эту переменную для получения IP-адресса удаленного узла ( броузера ), который делает запрос. Например, значение переменной окружения может быть следующим:

Переменная REMOTE_HOST

Скрипты используют эту переменную для того, чтобы получить имя узла, с которого делается запрос. Если сервер не знает имя узла, делающего запрос, то сервер должен присвоить значение переменной окружения REMOTE_ADDR и не присваивать значения переменной REMOTE_HOST . Напрмиер, для узла jamsa.com переменная окружения будет содержать следующее значение:

Переменная REMOTE_IDENT

Используется для того, чтобы получиь имя удаленного пользователя, делающего запрос к серверу. Программа Web-сервера представляет собой программное обеспечение. вызывающее ваш скрипт. Если HTTP Web-сервер поддерживает протокол RFS 931 (Authentication Server Protocol), то сервер установит эту переменную равной значению имени пользователя, которое имеется у сервера. Скрипты могут использовать эту переменную только для регестрации пользователя. Напрмер, если имя удаленного пользователя pschmauder и он назодится на удаленном узлеjamsa.com , то переменная примет следующее значение:

Переменная REMOTE_USER

Используется для того, чтобы получить имя удаленного пользователя без имени узла, с которого он производит запрос. Если сервер поддерживает идентификацию пользователя и скрипт является защищенным, то сервер установит имя пользователя и присвоит его этой переменной. Например, предположим, что именем удаленного пользователя является pschmauder . Тогда переменная будет выглядеть следующим образом:

Переменная REQUEST_METHOD

Используется для того, чтобы определить тип HTTP-запроса, который послан броузером серверу и служит для вызова скриптов. Эта переменная может принимать значения GET, HEAD илиPOST. Например, если броузер посылает GET-метод, то переменная окружения содержит следующее:

Переменная SCRIPT_NAME

Используется для того, чтобы определить виртуальный путь к скрипту, который будет запущен сервером. Например, если имеется URL http://www.jamsa.com/cgi-bin/someprog.exe, то переменная окружения примет следующее значение:

Переменная SERVER_NAME

Использутся для того, чтобы определитьимя домена ли IP-адрес комрьютера, на котором раположен Web-сервер. Например, когда сервер возвращает IP-адрес, переменная окружения будет иметь вид, подобный следующему:

Переменная SERVER_PORT

Используется для того, чтобы определить номер порта, который пользователь (броузер) использует для связи с Web-сервером. Если используется HTTP-порт по умолчанию, то эта величина равна 80. Если используется какой-то другой порт, например, http://www.jamsa.com:3000, то переменная принимает следующее значение:

Переменная SERVER_PROTOCOL

Используется для того, чтобы определить имя и номер выпуска протокола, используемогоклиентом (броузером) для того, чтобы послать запрос к Web-серверу. Анализируя содержание переменной, скрипт может идентифицировать имя и номер выпуска протокола, который он должен использовать при передаче данных серверу. Формат имени протокола и номера выпуска следующий: протокол/номер выпуска. Например, для HTTP 1.1 переменная окружения будет иметь следующий вид:

Переменная SERVER_SOFTWARE

Как вы знаете, Web-сервер исполняет скрипты CGI. Поскольку скрипт может испольняться по-разному для различных серверных программ, скрипты используют эту переменную для того, чтобы определить имя программы Web-сервера и ее номер версии. Формат имени Web-сервера и номер версии должен передаваться CGI следующим образом: имя/версия. Например, для FOLK WEB -сервера версии 1.01 переменная окружения будет иметь седующий вид:

Дополнительные переменные окружения

В дополнение к переменным окружения. обсуждавшимся ранее, сервер также помещает данные из заголовка запроса, полученного от клиента, в переменные окружения. Сервер присваивает значения переменным, чьи имена начинаются с префикса HTTP_, после которого идет имя заголовка. Сервер заменяет все символы переноса (-) в заголовке на (_). Сервер может также исключать любые заголовки, которые он уже обработал, используя переменные окружения, такие как AUTH_TYPE, CONTENT_TYPE и CONTENT_LENGTH.

Переменная HTTP_ACCEPT

Используется для того, чтобы определить, какие MIME-типы может принимать броузер. Они определены в HTTP-заголовках, которые броузер послал серверу. Как известно, MIME-тип задается в виде тип/расширение. Если имеется насколько MIME-типов, то они разделяются запятыми. Например, переменная окружения может принимать следующее значение:

Переменная HTTP_USER_AGENT

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

Опции командной строки CGI

Обычно CGI-скрипты используют командную строку в качестве входа для того, чтобы выполнить запрос ISINDEX, позволяющий добавить интерактивный поиск по ключевому слову к вашему HTML-документы. Однако не все серверные программы поддерживают ISINDEX-запрос. Броузер посылает запрос в виду командкной строки серверу. Программа сервера может идентифицировать входную командную строку, устанавливая, использовал ли броузер GET-метод HTTP и содержит ли строка URL символы uuencoded =.

Если броузер использует GET-метод HTTP и строка URL-поиска не содержит символы uuencoded =, то запрос осуществляется в форме командной строки. Перед тем как сервер вызовет соответствующий скрипт, серверная программа должна расщепить командную строку, используя знак (+), для отделения параметров. Затем сервер выполняет дополнительное декодирование ( если необходимо ) каждого параметра, переданного в URL-строке поиска, и хранит каждый параметр-строку в массиве, названную argv.

Дополнительное декодирование, выполняемое сервером, состоит в разделении отдельных строк, используя амперсанда (&) в качестве разделителя. Далее сервер расщепляет каждую из этих строк снова, используя знак (=) для того, чтобы отделить имя переменной, которое ставиться слева от знака (=), от значения переменной, которое стоит справа от (=). Сервер хранит число элементов, содержащихся в массиве argv, в переменной целого типа argс.

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

Стандартный ввод ( STDIN )

Когда броузер запрашивает сервер ( например, используя HTTP-метод POST ), информация, которую получает скрипт, приходит со стандартного дескриптора ввода stdin. Серверная программа посылает скрипту переменную окружения CONTENT_LENGTH. Эта переменная содержит число байт, которое сервер посылает скрипту через этот дескриптор. Скрипт может использовать значение переменной CONTENT_LENGTH для того, чтобы определить, сколько данных должно поступить со стандартного ввода. Сервер также снабжает скрипт переменной окруженияCONTENT_TYPE, которая помогает скрипту определить, как обрабатывать получаемые данные. В конце этого потока данных сервер может послать ( а может и не посылать ) маркер конца файла. Однако именно скрипт обязан определить, какой объем данных читать, и использует он для этого переменную окружения CONTENT_LENGTH.

Например, если форму использует HTTP-метод POST ( ) и посланные серверу данные закодированы следующим образом: name=alberta&husband=art, то сервер присвоит переменным CONTENT_LENGHT и CONTENT_TYPEследующие значения:

Стандартный вывод (STDOUT)

После того как CGI-скрипт закончит обрабатывать полученные от сервера данные, он должен посылать свой ответ серверу. Для того, чтобы послать свои данные серверу, он должен посылать их файловому дескриптору стандартного выводы STDOUT. В общем случае данные, которые скрипт посылает назад серверу, представляет собой HTTP-ответ, включающий заголовок, после которого идет пустая строка и за ней остальная часть ответа. Обычно выходом скрипта служат документы HTML, созданные скриптом.

Заголовки HTTP и их роль в обеспечении безопасности

Заголовки HTTP и их роль в обеспечении безопасности

В рамках проекта «Домены России» публикуется ежемесячный отчёт о распространённости HTTP-заголовков безопасности. Эта статья рассказывает о том, что собой представляют эти заголовки и какова их роль в обеспечении безопасной работы пользователя с веб-сайтом.

Введение

HTTP (Hyper Text Transfer Protocol) - протокол Веба. Именно по HTTP браузер взаимодействует с веб-сервером, загружая тот или иной веб-ресурс. HTTP - старый протокол, и в своих классических версиях устроен очень просто - клиент и сервер, установив соединение, обмениваются текстовыми запросами и ответами: клиент запрашивает документы, расположенные по указанному адресу, а сервер - передаёт их в ответ на запрос. Документы - это исходные коды веб-страниц, представляющие собой HTML- и CSS-код, файлы скриптов (например, Javascript), а также файлы изображений (картинки форматов .PNG, .GIF, .JPEG) и другие данные. Отметим, что существует суперсовременный протокол под названием HTTP/2 - этот протокол существенно отличается от классического HTTP (версий 1.0 и 1.1 или просто HTTP/1). Далее мы обсуждаем только классический вариант HTTP, который повсеместно используется, более того, для целей настоящей статьи, посвящённой HTTP-заголовкам, отличия HTTP/1 и HTTP/2 — не являются определяющими.

В HTTP запросы клиента содержат идентификаторы методов, которые обозначают способы обработки на стороне сервера. Так, запрос с методом GET - соответствует извлечению полного документа, находящегося по указанному адресу на сервере. GET повсеместно используется для извлечения кода веб-страниц. Метод POST - напротив, позволяет клиенту загрузить на сервер некоторый блок данных в определённом протоколом формате. Типичный способ использования POST - передача на сервер данных веб-формы (например, запоненной на сайте анкеты). Методы обозначаются простыми текстовыми строками.

HTTP в практике веба

Поскольку сценарии использования протокола HTTP в современном вебе достаточно сложные, запросы и ответы HTTP содержат, кроме идентификаторов методов и адресов документов, много дополнительной служебной информации. Самым известным примером здесь является поле User-Agent, в котором клиент указывает свой тип, название, версию. В частности, поле User-Agent позволяет веб-серверу определить тип браузера, который отправил запрос. User-Agent в классическом HTTP представляет собой текстовую строку, состоящую из идентификатора (собственно, "User-Agent") и значения, разделённых символом ":" (двоеточие). Так же записываются и другие HTTP-заголовки.

Дополнительные поля передаются и клиентом, и севером. Все эти поля представляют собой сочетание текстового имени поля и текстового же значения. Именно эти дополнительные поля в HTTP-ответе сервера и принято называть HTTP-заголовками, а идентификаторы - используются в качестве имён, по которым на конкретный заголовок ссылаются. Так, о поле с описанием типа браузера говорят как об "HTTP-заголовке User-Agent".

Как уже упоминалось выше, протокол HTTP - это протокол типа "клиент-сервер": клиент отправляет запросы, а сервер выполняет их (при возможности) и отправляет ответы. Клиентом, в типичной ситуации, выступает браузер, а сервер - это веб-сервер. Сессия работы с современным веб-сайтом включает множество HTTP-запросов и HTTP-ответов, которые могут направляться как последовательно, так и параллельно.

Веб-сервер использует HTTP-заголовки для того, чтобы передать клиенту расширенные сведения о настройках сервера в контексте HTTP, о правилах обработки HTTP-соединений, принятых на стороне сервера. Заголовки также позволяют отправить рекомендации по дальнейшему взаимодействию с сервером. Заголовки содержат и другую техническую информацию о соединении, например, cookie-файлы, используемые для авторизации. Другими словами, набор HTTP-заголовков сервера представляет собой небольшой текстовый справочник, при помощи которого клиент, в автоматическом режиме, определяет сценарий дальнейшей работы с данным веб-сервером.

До момента первого соединения с сервером, клиент, в общем случае, не может узнать, какие дополнительные параметры будут переданы сервером в заголовках, поэтому руководствуется настройками по умолчанию; однако после ответа сервера на первый запрос - клиент получает возможность скорректировать последующие запросы в соответствии с рекомендациями сервера, а также изменить способ интерпретации только что полученных от сервера данных. Последний аспект, в частности, позволяет заблокировать большие классы атак, направленных на пользовательские браузерные сессии, потому что браузер может преобразовать и отфильтровать данные до того, как отобразит страницу или её элемент для пользователя.

Безопасная версия HTTP – HTTPS – использует TLS (протокол Transport Layer Security) для защиты информации. HTTPS, с точки зрения части HTTP, работает полностью аналогично открытой версии, однако, так как канал защищён криптографическими методами, клиент и сервер получают механизмы проверки подлинности и целостности переданных данных. Такая проверка проводится за пределами HTTP. HTTPS существенно усиливает значение HTTP-заголовков, и многие из этих заголовков актуальны только в случае HTTPS.

Итак, HTTP-заголовки - это представленные в текстовом формате сведения о различных параметрах HTTP-сессии. Заголовки позволяют веб-серверу информировать браузер о настройках, которые следует применять для данного адреса и данного сайта. Эти настройки могут относиться как к текущей сессии, так и к последующим. Рассмотрим элементарный пример запроса и ответа HTTP (с заголовками):

Запрос (это GET-запрос, он отправляется клиентом в адрес сервера, в данном случае - обозначает извлечение индексного документа из корневой директории на сервере, "HTTP/1.1" - указывает на версию, используемую клиентом):

GET / HTTP/1.1
Host: www.google.com

(Здесь Host: - это служебный HTTP-заголовок _запроса_, обозначающий имя сервера, к которому обращается клиент: www.google.com, в данном случае.)

Ответ (HTTP-ответ с кодом статуса 200, обозначающим успешное выполнение - код статуса указан в первой строке):

HTTP/1.1 200 OK
Date: Fri, 24 Apr 2020 18:33:48 GMT
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN

Здесь нужно обратить внимание на две нижних строки, которые начинаются с обозначений X-XSS-Protection и X-Frame-Options. Это примеры _серверных_ HTTP-заголовков безопасности.

Заголовки безопасности

Часть серверных заголовков HTTP предназначены для повышения безопасности сессий при работе браузера с веб-сайтами. Эти заголовки называются "заголовками безопасности". Исторически, они вводились в употребление постепенно, в качестве ответа на возникавшие новые направления атак. Заголовки безопасности позволяют администратору веб-ресурса передать браузеру сведения, которые описывают рекомендованные администратором правила и политики работы клиента (браузера) с веб-сайтом. Поддержка и интерпретация заголовков различаются в деталях от браузера к браузеру (а также в разных версиях браузеров одной линейки), но базовые принципы во всех современных браузерах общие.

Вернёмся к двум заголовкам из примера выше.

X-Frame-Options. Этот заголовок определяет то, как браузер должен показывать соответствующую страницу в контексте встраиваемого отображения. Например, в HTML существует понятие "фрейма" (теги и ). "Фрейм" позволяет прозрачно встроить веб-страницу, соответствующую одному серверу, в некоторую область видимости внутри страницы, относящейся к другому серверу. Так показывается реклама на веб-сайтах: на основной странице выделяется визуальный блок, - обычно, фиксированного размера, - и внутри этого блока браузер показывает контент, полученный с совсем другого сайта (и сервера). Однако, при помощи той же конструкции с "фреймами", контент некоторого веб-сайта может быть встроен в страницу другого вопреки желанию владельца первого сайта. Это не просто позволяет злоумышленникам выдать чужой контент за свой, прозрачно подменив видимый адрес страницы, но и ввести пользователя в заблуждение относительно того, на каком сайте в действительности выполняются те или иные действия - например, пользователь кликает на какое-то изображение. Заголовок X-Frame-Options, если он поддерживается браузером, противодействует всем этим неприятностям.

Для X-Frame-Options, в современной версии, допускаются два значения - DENY и SAMEORIGIN. Заголовок считывается браузером и, если в качестве значения указано DENY, то браузер не станет показывать данную страницу внутри "фрейма". SAMEORIGIN - более мягкий вариант правила, допускающий демонстрацию страниц во "фреймах", если "охватывающая" страница принадлежит тому же источнику (впрочем, подробные детали того, как определяется, что источник двух страниц общий - достаточно туманны, но для понимания принципа можно считать, что это определяется по совпадающему имени домена).

Рассмотрим механизм применения заголовков в подробностях, на примере обработки браузером X-Frame-Options. Предположим, что браузер загружает страницу с адресом http://test.ru/page/. В HTML-коде этой страницы содержится конструкция , создающая "фрейм". Схема подразумевает указание адреса веб-ресурса, страница которого выводится внутри "фрейма". Пусть это адрес http://example.com/form/. Загрузив страницу с узла test.ru и обнаружив в её HTML-коде ссылку на http://example.com/form/, браузер выполнит соответствующий GET-запрос к серверу под доменом example.com и получит в составе ответа HTTP-заголовки. Если среди этих заголовков (которые формирует сервер example.com) обнаружится строка "X-Frame-Options: DENY", то браузер проигнорирует параметры и не выведет страницу http://example.com/form/ внутри "фрейма". Значение SAMEORIGIN - используется в том случае, если механизм "фреймов" применяется разработчиком непосредственно в рамках конкретного веб-ресурса, но при этом требуется, чтобы возможность использования "фреймов" не распространялась за рамки этого ресурса. X-Frame-Options регулирует не только конструкции и , но также и - принципы применяются те же.

Заголовок X-XSS-Protection. Этот заголовок управляет включением фильтра "кросс-сайтового скриптинга" на стороне браузера (заголовок считается устаревшим, но всё ещё рекомендован к использованию, так как позволяет защитить устаревшие же браузеры). "Кросс-сайтовый скриптинг" (сross-site scripting - XSS) - это распространённый инструмент для построения атак, которые базируются на внедрении дополнительного кода и навязывании специально сгенерированных HTTP-запросов в браузерные сессии, относящиеся к другим веб-сайтам, а не к сайту-источнику. Базовая логика атак XSS состоит в том, что навязанный скрипт или запрос исполняется в контексте другой сессии. Так, пользователь открывает в браузере веб-страницу некоторого сайта P, которая содержит специально подготовленный скрипт, вынуждающий браузер совершить, в контексте сохранённой сессии, запрос к сайту Q; так как сохранённая сессия может содержать активную авторизацию для сайта Q - запрос будет выполнен с соответствующими правами на сайте Q, как если бы сам пользователь открыл этот сайт в браузере и, например, отправил какое-нибудь сообщение. Заголовок X-XSS-Protection поддерживается не всеми современными браузерами, на смену ему приходит другой заголовок, позволяющий решать те же задачи, но не только их. Это Content-Security-Policy.

Content-Security-Policy (CSP) - самый насыщенный директивами и опциями заголовок безопасности. Он позволяет администратору сервера задать политики, определяющие загрузку браузером различных ресурсов и объектов, относящихся к данному адресу (или к странице). Например, политики, задаваемые Content-Security-Policy, определяют как и с каких именно серверов браузер может загружать скрипты, файлы изображений, дополнительные шрифты, плагины и другие элементы страницы. Но CSP не ограничивается этим - опций и директив очень много. Они разделяются на пять наборов: загрузочные директивы, документальные директивы, навигационные директивы, информирующие директивы и прочие директивы. Сколь-нибудь подробное рассмотрение составляющих всех этих наборов потребует отдельной статьи, поэтому мы лишь кратко опишем наборы директив.

Директивы загрузки CSP определяют допустимые источники (по адресам) для тех или иных ресурсов, ссылки на которые возникают при интерпретации исходных кодов страницы браузером. Так, при помощи директивы script-src CSP определяются допустимые источники JavaScript-файлов, а также способы проверки и обработки содержимого этих файлов.

Документальные директивы CSP регулируют контекст, в котором интерпретируется веб-страница целиком. Например, директива plugin-types ограничивает набор типов плагинов, допустимых для данного контекста документа, в частности, с помощью этой директивы можно разрешить загрузку и исполнение объектов Flash.

С помощью навигационных директив CSP задаются ограничения для адресов других документов и серверов, к которым может обращаться тем или иным способом пользователь в данном контексте страницы. Под обращением понимается, например, отправка веб-формы - то есть, соответствующая директива form-action ограничивает перечень адресов, на которые браузер будет передавать данные полей веб-формы.

Информирующие директивы CSP позволяют указать специальный адрес (URL), по которому браузер отправит типовой отчёт о нарушении политик, определённых в CSP. Такой адрес нужен для того, чтобы администратор сервера мог узнать, что на стороне клиента произошло некоторое нарушение или сбой — поскольку это может являться признаком атаки.

К набору прочих директив относится несколько не попавших в другие наборы - например, директива upgrade-insecure-requests, которая предписывает браузеру автоматически заменять возникающие в контексте документа "небезопасные" запросы (то есть, те, для которых указан протокол HTTP) на безопасные (HTTPS).

Заголовки Content-Security-Policy это хорошо развитый инструмент для управления поверхностью атаки на больших и сложно устроенных веб-проектах, которые, к тому же, используют контент, загружаемый пользователями. Например, средствами CSP можно запретить исполнение внешних скриптов для всех источников, кроме проверенных, при этом проверенные - остаются внешними: к ним могут относиться провайдеры контекстной рекламы или системы веб-аналитики.

Referrer-Policy - относится к другому типу заголовков безопасности: этот заголовок определяет, какие данные браузер может передать в HTTP-заголовке Referer, который используется, например, при обработке браузером "перехода по ссылке". Так, Referer может содержать адрес предыдущего ресурса, с которого пользователь перешёл на данный. То есть, сервер, обслуживающий целевой ресурс, видит, откуда пришёл пользователь. Чтобы сократить утечки информации, происходящие через этот заголовок, перечень данных, которые могут в нём передаваться, регулируется заголовком безопасности Referrer-Policy. Например, "Referrer-Policy: origin" - определяет, что в поле Referer браузер передаёт только часть полного адреса (URL), определяющую протокол и имя сервера: при переходе со страницы https://test.ru/from.html в Referer браузер запишет только https://test.ru/. (В браузерах есть и другие механизмы, ограничивающие Referer.)

Заголовок X-Content-Type-Options предписывает браузеру строго следовать перечню идентификаторов типов контента, указанных в поле заголовка Content-Type. Предполагается, что тип данных (или контента), передаваемого сервером в HTTP-ответе, корректно обозначен в HTTP-заголовке. Однако в спорных случаях браузеры могут использовать собственные гибкие алгоритмы определения типа контента на основании самих данных. Это помогает, например, корректно обработать файлы изображений, которые по ошибке передаются с несоответствующим типом. Заголовок X-Content-Type-Options позволяет прямо запретить браузеру использование этих алгоритмов. Заголовок может блокировать атаки с подменой данных, при которых браузер из-за ошибочной интерпретации типа выполняет вредоносный код.

Особенно важен заголовок безопасности Strict-Transport-Security. Оно сообщает браузеру, что при соединении с данным веб-ресурсом следует использовать только безопасный протокол HTTPS. Этот заголовок противодействует атакам, использующим понижение уровня защиты, а именно - замену указанного в адресе ресурса протокола с https:// на http://. Такую замену можно проделать различными способами, в том числе, прямым вмешательством в незащищённый HTTP-трафик. При этом, пользователь может не заметить разницы в типе соединения, а отсутствие TLS позволяет осуществить и подмену адреса, сохранив знакомое доменное имя в адресной строке браузера.

Заголовок Public-Key-Pins - это механизм, позволяющий передать клиенту отпечатки серверных криптографических ключей TLS, которые являются допустимыми для данного сервера. Это известный по другим безопасным протоколам (например, SSH) метод запоминания ключей "при первой встрече". Метод позволяет в дальнейшем обнаружить подмену, даже если такая подмена проводится при участии доверенного удостоверяющего центра. Данный заголовок ранее полностью поддерживался распространёнными браузерами, в частности, Mozilla Firefox, но, к сожалению, сейчас практически выведен из поддержки (в актуальных версиях Firefox требуется включать поддержку вручную, а корректная работа не гарантируется).

Два последних из упомянутых заголовков особенно чувствительны к используемому протоколу - HTTP или HTTPS. Дело в том, что в случае "небезопасной" версии HTTP активный атакующий может удалить или подменить любые заголовки, соответственно, теряется смысл в отправке заголовков, управляющих использованием TLS: они просто могут не дойти до клиента, а пользователь ничего не заметит. При этом однократная передача заголовка по доверенному каналу, через HTTPS, позволяет браузеру запомнить настройки - так как в этом случае сервер-источник аутентифицирован, то и содержимое заголовков оказывается доверенным. Это же наблюдение распространяется и на другие заголовки: если модель атаки подразумевает активную подмену любого трафика, то никакой из заголовков уже не может приниматься к сведению при передаче по HTTP. Тем не менее, чаще используется более слабая модель, в которой атакующий может подменять только какие-то фрагменты на веб-страницах (обычно, на сервере) и передавать произвольную информацию с контролируемого сервера в ответ на запросы браузера. В этой модели ряд HTTP-заголовков безопасности имеют смысл и для открытой версии (HTTP), например, Content-Security-Policy и X-Frame-Options.

Мы рассмотрели наиболее важные и распространённые заголовки безопасности HTTP. Эти заголовки предоставляют гибкие инструменты, позволяющие существенно усилить безопасность использования веб-ресурсов пользователями. Отметим, что добавление заголовков к конфигурации веб-сервера в большинстве случаев является элементарной операцией, выполнение которой под силу даже начинающему системному администратору.

Горин Павел/ автор статьи

Павел Горин — психолог и автор популярных статей о внутреннем мире человека. Он работает с темами самооценки, отношений и личного роста. Его экспертность основана на практическом консультировании и современных психологических подходах.

Понравилась статья? Поделиться с друзьями:
psihologiya-otnosheniy.ru
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: