Какова была мотивация внедрения предполетных запросов?
Предшествующие запросы были введены, чтобы браузеры могли убедиться, что они имели дело с сервером, поддерживающим CORS, перед отправкой определенных запросов. Этими запросами были определены те, которые были как потенциально опасными (с изменением состояния), так и новыми (невозможно до CORS из-за Same Origin Policy). Использование запросов предполетного знака означает, что серверы должны отказаться (путем надлежащего реагирования на предполетный период) на новые, потенциально опасные типы запросов, которые CORS делает возможным.
Спецификация puts it this way: «Для защиты ресурсов от запросов кросс-происхождения, которые не могли исходить от определенных пользовательских агентов до того, как эта спецификация существовала, предпродажный запрос делается для обеспечения того, чтобы ресурс знал об этой спецификации».
Можете ли вы привести мне пример?
Предположим, что пользователь зарегистрировался на своем банковском сайте по адресу A.com
. Когда они направляют свой браузер на мой сайт по адресу B.com
, на моей странице есть Javascript, который отправляет злонамеренный DELETE
запрос на адрес A.com/account
. Поскольку пользователь регистрируется в A.com
в этом сеансе браузера, запрос включает в себя файл cookie аутентификации пользователя для этого домена. Если префайлы не существовали, браузер будет идти вперед и отправлять этот запрос, поскольку в CORS сервер должен определить, разрешен ли запрос.
А что, если банковский сайт на A.com
не знает о CORS? Он может с радостью выполнить DELETE
. Он не был предназначен для предотвращения этой атаки, потому что до того, как существовала CORS, политика одинакового происхождения браузера не позволила бы ей отправить такой запрос. Сервер полагается на это предположение.
В отличие от этого, если браузер сначала отправляет запрос перед полетом, сервер не сможет правильно ответить. Это говорит браузеру, что этот сервер не участвует в CORS, и поэтому он не должен отправлять потенциально опасные DELETE
.
Почему все эти проблемы с браузером, не может злоумышленник просто отправить запрос DELETE
со своего компьютера?
Уверенный, но такой запрос не будет содержать файлы cookie пользователя. Атака, которая предназначена для предотвращения, полагается на то, что браузер отправит файлы cookie (в частности, информацию аутентификации для пользователя) для другого домена вместе с запросом.
Это звучит как Cross-Site Request Forgery, где форма на сайте B.com
может POST
к A.com
с печеньем пользователя и нанести ущерб.
Это верно. Другим способом для этого является то, что запросы предполета были созданы, чтобы не увеличивать поверхность атаки CSRF для серверов, не поддерживающих CORS.
Но, глядя на requirements для «простых» запросов, которые не требуют preflights, я вижу, что POST
все еще разрешено. Это может изменить состояние и удалить данные так же, как DELETE
!
Это правда! CORS не защищает ваш сайт от атак CSRF. Опять же, без CORS вы также не защищены от атак CSRF. Цель предполетных запросов - просто ограничить поверхность атаки CSRF тем, что уже существовало в мире pre-CORS.
Вздох. Хорошо, я неохотно согласен с необходимостью предполетных запросов. Но почему мы должны делать это для каждого ресурса (URL) на сервере? Сервер либо обрабатывает CORS, либо нет.
Уверены ли вы в этом? Для нескольких серверов нередко обрабатываются запросы для одного домена. В частности, может случиться так, что запросы для A.com/url1
обрабатываются одним типом сервера, а запросы для A.com/url2
обрабатываются сервером другого типа. Как правило, сервер, обрабатывающий один ресурс, не может гарантировать безопасность всех ресурсов в этом домене.
Изобразительное. Пойдем на компромисс. Давайте создадим новый заголовок CORS, который позволяет серверу точно указать, на какие ресурсы он может работать, так что можно избежать дополнительных запросов перед полетом для этих URL-адресов.
Полезная идея! На самом деле для этой цели был предложен заголовок Access-Control-Policy-Path
. В конечном счете, однако, это было исключено из спецификации, apparently, потому что некоторые серверы неправильно реализовали спецификацию URI таким образом, что запросы к путям, которые выглядели безопасными для браузера, на самом деле не были бы безопасными на сломанных серверах.
Было ли это разумным решением о приоритете безопасности в отношении производительности, позволяя браузерам немедленно реализовать спецификацию CORS без риска для существующих серверов? Или это близоруко, чтобы обречь интернет на трату впустую и удвоить латентность, просто чтобы разместить ошибки на определенном сервере в определенное время?
Мнения разные.
Ну, по крайней мере, браузеры будут кэшировать предполетные баллы для одного URL-адреса?
Да. Хотя, вероятно, не очень долго. В браузерах WebKit максимальное время кэша перед полетом составляет currently 10 minutes.
Ugh. Хорошо, если я знаю, что мои серверы осведомлены о CORS и поэтому не нуждаются в защите, предлагаемой запросами предполетной защиты, есть ли способ избежать их?
Ваш единственный реальный вариант - убедиться, что вы встретите requirements для «простых» запросов. Это может означать отказ от пользовательских заголовков, которые вы могли бы включить (например, X-Requested-With
), лежащих около Content-Type
или более.
В любом случае, вы должны убедиться, что у вас есть надлежащая защита CSRF, поскольку спецификация CORS не касается отклонения «простых» запросов, в том числе небезопасных POST
. As the specification puts it: «Ресурсы, для которых простые запросы имеют значение, отличные от поиска, должны защищать себя от подделки запросов на межсайтовый запрос».
Если это так, то почему оно отправляется по каждому запросу? Один запрос на сервер должен быть достаточным, чтобы определить, знает ли сервер о CORS. –
Спецификация включает [preflight-result-cache] (http://www.w3.org/TR/cors/#preflight-result-cache) в браузере. Таким образом, несмотря на то, что он по-прежнему чувствует себя неаккуратно и неэффективно, кажется, что можно настроить новые серверы на кеш-кеш неограниченно. –
Я согласен с тем, что запросы предварительной проверки не связаны по своей сути с безопасностью, но похоже, что использование предпродажных запросов CORS определенно по соображениям безопасности. Это не просто проверка здравомыслия, чтобы предотвратить относительно безвредный сценарий ошибок. Если пользовательский агент слепо отправил запрос на сервер, ложно предполагая, что сервер реализовал CORS, он, скорее всего, будет принимать подделки с запросами на кросс-сайт. Несмотря на то, что ответ не читается javascript, сервер, возможно, уже предпринял некоторые нежелательные действия, такие как удаление учетной записи или банковский перевод. –