Какова была мотивация введения предварительных запросов?
Предварительные запросы были введены так, чтобы браузер мог быть уверен, что он имеет дело с сервером, поддерживающим CORS, перед отправкой определенных запросов. Эти запросы были определены как потенциально опасные (с изменением состояния) и новые (невозможные до CORS из-за единой политики происхождения ). Использование запросов предварительной проверки означает, что серверы должны подписаться (путем правильного ответа на предварительную проверку) на новые, потенциально опасные типы запросов, которые CORS делает возможным.
В этом смысл этой части спецификации : «Для защиты ресурсов от запросов разных источников, которые не могли быть отправлены определенными пользовательскими агентами до того, как эта спецификация существовала, делается предварительный запрос, чтобы гарантировать, что ресурс осведомлен об этой спецификации».
Можете ли вы дать мне пример?
Давайте представим, что пользователь браузера вошел на свой банковский сайт по адресу A.com
. Когда они переходят к вредоносным программам B.com
, эта страница содержит некоторый Javascript, который пытается отправить DELETE
запрос A.com/account
. Поскольку пользователь вошел в систему A.com
, этот запрос, если он будет отправлен, будет включать файлы cookie, которые идентифицируют пользователя.
До CORS браузер Same Policy Policy блокировал бы его от отправки этого запроса. Но так как целью CORS является сделать возможным только такой тип связи между источниками, это больше не подходит.
Браузер может просто отправить DELETE
и позволить серверу решить, как его обработать. Но что, если A.com
не знает протокол CORS? Это может пойти дальше и выполнить опасное DELETE
. Можно было бы предположить, что - из-за одинаковой политики происхождения браузера - он никогда не мог получить такой запрос, и, таким образом, он никогда не был защищен от такой атаки.
Для защиты таких серверов, не поддерживающих CORS, протокол требует, чтобы браузер сначала отправил предварительный запрос . Этот новый тип запроса - это то, на что только серверы, поддерживающие CORS, могут отвечать должным образом, позволяя браузеру узнать, безопасно ли отправлять фактическое сообщение DELETE
.
Почему весь этот шум вокруг браузера, не может ли злоумышленник просто отправить DELETE
запрос со своего компьютера?
Конечно, но такой запрос не будет включать куки пользователя. Предназначенная для предотвращения атаки атака основана на том факте, что браузер будет отправлять файлы cookie (в частности, информацию об аутентификации для пользователя) для другого домена вместе с запросом.
Это звучит , как Cross-Site Request Подделка , где форма на сайте B.com
банке , POST
чтобы A.com
с печеньем пользователя и нанести ущерб.
Вот так. Это можно сделать так, что предварительные запросы были созданы таким образом, чтобы не увеличивать поверхность атаки CSRF для серверов, не поддерживающих CORS.
Но, глядя на требования к «простым» запросам, которые не требуют предварительных проверок, я вижу, что POST
это все еще разрешено. Это может изменить состояние и удалить данные, как DELETE
!
Это правда! CORS не защищает ваш сайт от CSRF-атак. Опять же, без CORS вы также не защищены от CSRF-атак. Цель предварительных запросов - ограничить воздействие CSRF на то, что уже существовало в мире до CORS.
Вздох. ОК, я неохотно принимаю необходимость предварительных запросов. Но почему мы должны делать это для каждого ресурса (URL) на сервере? Сервер либо обрабатывает CORS, либо нет.
Вы уверены, что? Многочисленные серверы нередко обрабатывают запросы для одного домена. Например, это может быть случай, когда запросы A.com/url1
обрабатываются одним видом сервера, а запросы A.com/url2
обрабатываются другим типом сервера. Как правило, сервер, обрабатывающий один ресурс, не может гарантировать безопасность всех ресурсов в этом домене.
Хорошо. Давай пойдем на компромисс. Давайте создадим новый заголовок CORS, который позволит серверу точно указывать, за какие ресурсы он может говорить, чтобы избежать дополнительных предварительных запросов к этим URL-адресам.
Хорошая идея! На самом деле, заголовок Access-Control-Policy-Path
был предложен именно для этой цели. В конечном счете, однако, это было исключено из спецификации, по- видимому, потому что некоторые серверы неправильно реализовали спецификацию URI таким образом, что запросы к путям, которые казались безопасными для браузера, на самом деле не были бы безопасны на сломанных серверах.
Было ли это разумным решением, которое отдавало приоритет безопасности над производительностью, позволяя браузерам немедленно внедрять спецификацию CORS, не подвергая риску существующие серверы? Или было недальновидно обречь интернет на потерю пропускной способности и удвоить задержку, просто чтобы учесть ошибки на конкретном сервере в определенное время?
Мнения расходятся.
Ну, по крайней мере, браузеры будут кэшировать предпечатную проверку для одного URL?
Да. Хотя, вероятно, не очень долго. В браузерах WebKit максимальное время кеширования перед полетом в настоящее время составляет 10 минут .
Вздох. Что ж, если я знаю, что мои серверы поддерживают CORS и, следовательно, не нуждаются в защите, предоставляемой предварительными запросами, есть ли способ избежать их?
Ваш единственный реальный вариант - убедиться, что вы соответствуете требованиям «простых» запросов. Это может означать исключение пользовательских заголовков, которые вы в противном случае включили бы (например X-Requested-With
), ложь о Content-Type
или больше.
Что бы вы ни делали, вы должны убедиться в наличии надлежащих средств защиты CSRF, поскольку в спецификации CORS не рассматриваются отклонения «простых» запросов, в том числе небезопасных POST
. Как сказано в спецификации : «ресурсы, для которых простые запросы имеют значение, отличное от извлечения, должны защищать себя от подделки межсайтовых запросов».