Ожидается ли, что мой сервер вернет 200 для методов HTTP OPTIONS, когда точка подключения запрещена для текущего пользователя?

Читая различные документы (такие как w3c CORS), я должен сказать, что OPTIONS действительно не кажется, что хорошо задокументировано на всех.

Мне интересно, правильно ли делает мой REST-сервер, который возвращает 403, если клиент пытается получить доступ к запрещенной точке подключения (существует она или нет, даже не всегда имеет значение, хотя иногда сервер может возвращать 404 вместо.)

Однако документация OPTIONS, похоже, не предполагает, что такой код возврата действителен.

Я нашел этот stackoverflow Q/A, где принятый ответ, кажется, говорит, что мы можем вернуть любой код ошибки.

Я бы предположил, что это будет дыра в безопасности, позволяющая OPTIONS проходить, когда пользователю это не разрешено. В то же время OPTIONS определяет заголовок Access-Control-Allow-Credentials, и я не понимаю, как я мог бы сделать этот заголовок полезным, если бы я возвращал 403 в таких точках соединения. (Другими словами, для меня это звучит противоречиво.)


person Alexis Wilke    schedule 29.01.2019    source источник
comment
И на самом деле, если я обнаружу 403 по пути, я могу сгенерировать заголовок Access-Control-Allow-Credentials в этот момент.   -  person Alexis Wilke    schedule 29.01.2019


Ответы (1)


Краткий ответ: если вы действительно хотите, чтобы ответ OPTIONS был полезен для включения CORS сервера, вам не следует возвращать 403 только потому, что пользователь не вошел в систему.

Подробности:

Сервер всегда может вернуть 403 для запроса OPTIONS. Протокол CORS не требует, чтобы ваш сервер возвращал 2xx успешный ответ на OPTIONS запрос. Но если ваш сервер не возвращает 2xx для OPTIONS запросов к определенному URL-адресу, предварительные OPTIONS запросы CORS к этому URL не будут выполнены. Так что, если вы на самом деле хотите, чтобы это произошло, то ответ 403 — это нормально, так же как и ответ 405 или 501 или любой другой код ответа, который может иметь значение, подходящее для вашего конкретного случая.

Но важно помнить, что протокол CORS требует, чтобы браузеры никогда не отправляли учетные данные для аутентификации в составе запроса CORS preflight OPTIONS. Таким образом, если ваш сервер настроен на требование аутентификации, чтобы OPTIONS запросов давали 2xx успешных ответов, то все предварительные проверки CORS, поступающие из браузеров, будут завершаться ошибкой в ​​100% случаев. Другими словами, вы гарантируете, что все запросы, которые поступают на сервер из внешнего кода JavaScript, работающего в браузере, и которые добавляют настраиваемые заголовки ответа (например, заголовки Content-Type или Authorization), не будут выполняться, и поэтому будут запускаться предварительные проверки.

Я не знаю какой-либо конкретной дыры в безопасности, которая может возникнуть, если отвечать 2xx на неаутентифицированные OPTIONS запросы (от непроверенных пользователей). Это не позволяет пользователям получать с вашего сервера какую-либо информацию, кроме той, которую вы намеренно решили поместить в заголовки ответа, которые вы отправляете в ответ на запрос OPTIONS. И, конечно же, это не мешает вам запрашивать аутентификацию для GET или POST или любых других методов. Но с точки зрения протокола CORS, это единственный способ для вашего сервера указать, какие методы и заголовки запросов он разрешает в запросах от внешнего JavaScript.


Также обратите внимание: текущие активно поддерживаемые требования для CORS определены в спецификации Fetch https://fetch.spec.whatwg.org. Спецификация https://w3.org/TR/cors устарела, больше не поддерживается и не должна ни для чего (см. https://w3.org/2017/08/16-webappsec-minutes.html#item03 и ответ на https://stackoverflow.com/a/45926657/441757).

Я не знаю, почему спецификация https://w3.org/TR/cors не уже был четко помечен как устаревший, но я постараюсь убедиться, что он будет помечен как таковой в ближайшее время.

person sideshowbarker    schedule 29.01.2019
comment
Да, удачи в реализации этого. Последнее, что я слышал (от @annevk), никого в W3 не беспокоит, что он помечен как устаревший, поэтому он просто лежит там. Имейте в виду, я думаю, что в некотором смысле документ W3 лучше написан для разработчиков интерфейса — спецификация Fetch действительно написана для разработчиков браузеров... - person roryhewitt; 04.02.2019