Когда Firefox устанавливает нулевой заголовок Origin в запросах POST?

Как вы можете видеть из этого потока Bugzillaтакже), Firefox не всегда отправляет заголовок Origin в запросах POST. RFC заявляет, что его не следует отправлять в определенных неопределенных контекстах, "чувствительных к конфиденциальности". Mozilla определяет эти контексты здесь.

Я хотел бы знать, являются ли это единственными ситуациями, когда Firefox не отправляет заголовок Origin. Насколько я могу судить, он также не будет отправлять запросы POST (хотя Chrome и IE будут это делать), но я не могу подтвердить это в документации. Это где-то перечислено, что я скучаю?

Благодарю.

3 ответа

Решение

Насколько требуют спецификации, вопрос выше должен быть разделен на пару ответов:

  • Когда браузеры должны отправить заголовок Origin
  • Когда браузеры должны внутренне установить источник в значение, которое будет сериализовано как null

Я сомневаюсь, что то, что требуется Firefox для этого (где оно отличается от спецификации), перечислено. Но что касается перечисления спецификационных требований, здесь они, в деталях, состоят из двух частей:

Когда браузеры должны отправить заголовок Origin

Ответ на вопрос Когда браузеры должны отправлять заголовок Origin? это Origin заголовок отправляется только для любого запроса, который спецификация Fetch определяет как запрос CORS:

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

Фактическое утверждение в спецификации Fetch, которое требует от браузеров отправлять Origin заголовок для всех запросов, чей метод не GET ни HEAD это:

Если установлен флаг CORS или метод httpRequest не является GET ни HEAD, а затем добавить Origin Происхождение / httpRequest, сериализованное и закодированное в UTF-8, в список заголовков httpRequest.

Так что для отправки требуется браузер Origin для всех POST запросы, в том числе одного происхождения POST s (которые по определению в Fetch на самом деле являются "запросами CORS" - даже если они одного происхождения).


Примечание. Выше описано, как спецификация Fetch в настоящее время определяет требования, в связи с изменением спецификации в 2016-12-09. До тех пор требования были другими:

  • ранее нет Origin был отправлен для одного и того же происхождения POST
  • ранее нет Origin был отправлен на отправку перекрестного происхождения из <form> (без CORS)

Поэтому я думаю, что поведение Firefox, описанное в этом вопросе, соответствует тому, что ранее требовалось для спецификации, а не тому, что требует спецификация в настоящее время.


Другие случаи, когда браузеры должны отправлять Origin заголовок - это любые случаи, когда запрос сделан с установленным "флагом CORS", который, насколько HTTP(S) запросы, кроме случаев, когда режим запроса navigate , websocket , same-origin , или же no-cors,

XHR всегда устанавливает режим на cors, Но с Fetch API эти режимы запросов можно установить с помощью mode поле аргумента объекта init для fetch(…) метод:

fetch("http://example.com", { mode: 'no-cors' }) // no Origin will be sent

Наряду с этим, для любого элемента с crossorigin атрибут (он же "атрибут установки CORS), спецификация HTML требует, чтобы браузеры установили режим запроса на cors (и отправить Origin заголовок).

В противном случае для любых элементов, инициирующих запросы (скрипты, таблицы стилей, изображения, медиа-элементы), режим для запросов по умолчанию равен no-cors, что означает нет Origin Заголовок отправляется для них.

Так что выше приведены подробности об условиях, при которых браузеры отправляют Origin заголовок.

Следующая часть ответа о том, когда начальное значение будет установлено на null,

Когда браузеры должны установить origin на значение, которое будет сериализовано как null

Отдельно от требований, когда браузеры должны отправлять Origin заголовок - это требования, когда браузеры должны установить источник в null, которые определены в следующих спецификациях:

Спецификация HTML использует термин непрозрачное происхождение и говорит следующее:

Внутреннее значение, без сериализации, из которого оно может быть воссоздано (оно сериализуется как "ноль" для ASCII-сериализации источника), для которого единственной значимой операцией является проверка на равенство.

Другими словами, везде, где в спецификации HTML указано непрозрачное происхождение, вы можете перевести это на null,

Спецификация HTML требует, чтобы браузеры устанавливали непрозрачный источник или уникальный источник в следующих случаях:

  1. Изображения перекрестного происхождения (включая перекрестное происхождение img элементы)
  2. Медиа-данные перекрестного происхождения (включая перекрестное происхождение video а также audio элементы)
  3. Любой документ, сгенерированный из data: URL
  4. любой iframe с sandbox атрибут, который не содержит значение allow-same-origin
  5. Любой документ, программно созданный с использованием createDocument() , так далее.
  6. Любой документ, который не имеет контекста просмотра создателя
  7. Ответы, которые являются ошибками сети
  8. Должна ли политика безопасности контента блокировать ответ навигации на запрос навигации типа от источника в цели? Алгоритм возвращает Заблокированный при выполнении в ответе навигации

Спецификация Fetch требует, чтобы браузеры устанавливали в качестве источника "глобально уникальный идентификатор" (что в основном означает то же самое, что и "непрозрачное происхождение", что в основном означает null …) В одном случае:

  1. Перенаправляет через происхождение

Спецификация URL требует, чтобы браузеры устанавливали непрозрачное происхождение в следующих случаях:

  1. За blob: URL - адрес
  2. За file: URL - адрес
  3. Для любых других URL, чья схема не является одной из http , https , ftp , ws , wss , или же gopher,

Но важно понимать, что только потому, что браузер внутренне установил непрозрачное происхождение - по сути, null - это не обязательно означает, что браузер отправит Origin заголовок. Так что смотрите первую часть этого ответа, чтобы узнать, когда браузеры должны отправлять Origin заголовок.

Для меня это происходило в суперстандартной форме POST с относительным URL-адресом на локальном хосте и, похоже, было вызвано тем, что

      <meta name="referrer" content="no-referrer">

в <head>.

Изменение его на

      <meta name="referrer" content="same-origin">

казалось, сделал Firefox счастливее.

Я хотел добавить некоторую информацию к великолепному ответу @sideshowbarker , который стал наиболее полным источником по этой теме и даже связан с MDN . Чтобы дополнить этот ответ, я рассмотрел различные спецификации и выявил некоторые изменения, произошедшие с момента первой публикации ответа. Я также систематизировал информацию, чтобы ее было легче читать. Кроме того, я использовал ссылки на WebArchive начала 2023 года вместо прямых ссылок, поскольку в будущем спецификации могут измениться.

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

Используйте их в качестве руководства, а если вы не уверены, обязательно проведите тесты.


Как упомянул user441757 , различные спецификации определяют нулевое значение. заголовок как:

  • непрозрачное происхождение
  • нулевое происхождение

Благодаря этому мы можем фильтровать спецификации, чтобы выяснить, когдаOriginзаголовокnull:

  • или запросы, которые не допускают совместное использование ресурсов между источниками (CORS) или используют веб-сокеты . Для всех других режимов запроса , использующихsame-origin,navigateили заголовок Origin опускается. Некоторые веб-API позволяют указать , например , а другие имеют значения по умолчанию, например запрос внешнего ресурса: 1, 2.
    • Любой встроенный HTML-элемент, который запрашивает свое содержимое через URL-адрес. Эти элементы включают в себя<link>,<script>,<img>,<audio>,<video>,<object>,<embed>, и . Эти HTTP-запросы используютno-corsрежим по умолчанию, если толькоcrossoriginАтрибут установлен в элементе HTML. Обратите внимание, что<canvas>,<math>, и<svg>не включены, так как не могут запрашивать данные из внешних ресурсов (например, с помощьюsrcатрибут). 1, 2, 3
    • Любой или запрос, где опция имеет значение "navigate", "same-origin", или "no-cors". По умолчанию,fetch()использует режим. 1, 2
    • (Примечание: , в отличие от не позволяет устанавливать a и по умолчанию равно , что означает, что все отправляются с заголовком Origin. )4
  • Referrer-Policy установлен в  no-referrer для любых запросов, которые не используют метод или и не используют или . 5
  • Ответы, которые являются сетевыми ошибками . Статус HTTP-ответа 404 или 500 не является сетевой ошибкой, поскольку запрос успешно достиг сервера. Скорее неверный протокол, заголовок или место, где сервер не может отправить ответ. 6
  • Content-Security-Policy (CSP) заблокировал ответы навигации. Термин «навигационные ответы» относится к местам, к которым пользователь может перейти (через<a>, ,window.location) или отправьте форму (через<form>). ответы не считаются навигационными ответами. 7
  • Схемы URL :
    • Любой встроенный встроенный файл, созданный по схеме 8.
    • В схеме может отсутствовать заголовок Origin (зависит от браузера) 9
    • В некоторых случаях для blob:схема 10
    • Любой другой URL-адрес, схема которого не является одной из http, https, ftp, ws, wssили gopher 11
  • Некоторые контексты просмотра не имеют Origin . Контекст просмотра — это среда, в которой отображается веб-страница или приложение, которая может быть вкладкойокном  или даже частями страницы, например  фреймом  или  iframe . Создатель (в предыдущих спецификациях HTML он назывался «контекстом просмотра создателя» ) — это контекст просмотра, который отвечал за создание другого контекста просмотра. Существует два типа создателей: открывающий контекст просмотра (например, щелчок по ссылке на другую страницу, страница, в которую вставлена ​​ссылка, является открывающим) и родительский контекст просмотра (например, страница, встраивающая iframe, является родительским контекстом просмотра). Спецификация HTML рассматривает следующие случаи без заголовка Origin:
    • Любой <iframe>с sandboxатрибут, который не содержит значения  allow-same-origin12
    • Любой документ, созданный программным путем с использованием контекста просмотра создателя или не имеющий его. 13, 14

Использованная литература:

1 В спецификации выборки указано, что Origin включен для всех запросов, кроме GETили HEAD.
2
3 Режим по умолчанию Request()конструктор, используемый для fetchи встроенные элементы HTML
4. В спецификации XHR указано, что режим по умолчанию XMLHttpRequestустановлено на cors
5 В спецификации выборки указано, что В спецификации выборки это упоминается в пункте № 3.1.modeс или websocketотправляются с заголовком Origin, исключая все остальные режимы.
6 Спецификация HTML гласит, что сетевая ошибка не должна возвращать никакие параметры навигации, включая происхождение. См. пункт № 21 (не № 19.21).
7 В спецификации HTML указано, что «заблокированный» ответ CSP приводит к сбою сети. См. пункт № 6.5 , который в спецификациях CSP определяется как сетевая ошибка , устраняемая в ссылке 5.
8 В спецификации HTML говорится, что data:Схема возвращает непрозрачный источник.
9
10 В спецификации URL указано, что читатель должен решить, как обрабатывать непрозрачного источника использованияfile:
11 В спецификации FileAPI перечислены некоторые конкретные случаи В. »спецификации URL перечислены эти схемы URL и резервные варианты
. 12 «непрозрачного происхождения В спецификации HTML указано, что для этот контекст случая iframe. См. пункт № 5.
13 Спецификация HTML гласит, что контекст без просмотра имеет «непрозрачное происхождение» . Более того, спецификация HTML гласит, что Document's' создано с createDocument()не иметь контекста просмотра

Другие вопросы по тегам