Что остановить вредоносный код от подмены заголовка "Origin", чтобы использовать CORS?

Как я понимаю, если клиентская сторона script, запущенная на странице с сайта foo.com, хочет запросить данные с bar.com, в запросе он должен указать заголовок Origin: http://foo.com, и бар должен ответить с Access-Control-Allow-Origin: http://foo.com.

Что нужно, чтобы остановить вредоносный код с сайта roh.com от простого подмены заголовка Origin: http://foo.com для запроса страниц из панели?

Ответ 1

Браузеры контролируют настройку заголовка Origin, и пользователи не могут переопределить это значение. Таким образом, вы не увидите заголовок Origin, подделанный из браузера. Злоумышленник может создать запрос на завивание, который вручную устанавливает заголовок Origin, но этот запрос будет поступать извне браузера и может не содержать информацию о браузере (например, файлы cookie).

Помните: CORS не является безопасностью. Не полагайтесь на CORS, чтобы защитить свой сайт. Если вы используете защищенные данные, используйте файлы cookie или токены OAuth или что-то иное, кроме заголовка Origin, чтобы защитить эти данные. Заголовок Access-Control-Allow-Origin в CORS только диктует, в каком происхождении должно быть разрешено делать запросы с кросс-началом. Не полагайтесь на это ни для чего большего.

Ответ 2

TLDR: Ничто не мешает вредоносному коду подделать источник. Когда это произойдет, ваш сервер никогда не узнает об этом и будет реагировать на запросы. Иногда эти запросы стоят дорого. Поэтому не используйте CORS вместо любого типа защиты.


Я недавно играл с CORS и задавал себе тот же вопрос. Я обнаружил, что браузер может быть достаточно умным, чтобы знать поддельный запрос CORS, когда он его видит, но ваш сервер не такой умный.

Первое, что я обнаружил, было то, что заголовок Origin - это HTTP имя запрещенного заголовка, которое нельзя изменить программно. Это означает, что вы можете изменить его примерно за 8 секунд, используя Изменить заголовки для Google Chrome.

Чтобы проверить это, я настроил два клиентских домена и один серверный домен. Я включил белый список CORS на сервере, который разрешал запросы CORS от клиента 1, но не от клиента 2. Я тестировал оба клиента, и действительно запросы CORS клиента 1 выполнялись успешно, в то время как сбой клиента 2.

Затем я подделал заголовок клиента 2 Origin, чтобы он соответствовал заголовку клиента 1. Сервер получил поддельный заголовок Origin и успешно прошел проверку белого списка (или потерпел неудачу, если вы наполовину пустой парень). После этого Сервер работал должным образом, потребляя все ресурсы, которые он был предназначен для потребления (вызовы базы данных, отправка дорогих писем, отправка еще более дорогих смс-сообщений и т.д.). Когда это было сделано, сервер с радостью отправил поддельный заголовок Access-Control-Allow-Origin обратно в браузер.

В прочитанной мной документации указано, что полученное значение Access-Control-Allow-Origin должно точно соответствовать значению Origin, отправляемому в запросе. Они совпадали, поэтому я удивился, увидев следующее сообщение в Chrome:

XMLHttpRequest не может загрузить http://server.dev/test. Заголовок 'Access-Control-Allow-Origin' имеет значение http://client1.dev это не равно предоставленному источнику. Происхождение http://client2.dev Поэтому доступ запрещен.

Документация, которую я читаю, не является точной. Вкладка сети Chrome четко отображает заголовки запроса и ответа как http://client1.dev, но в ошибке вы можете увидеть, что Chrome каким-то образом знает, что реальным источником был http://client2.dev, и правильно отклоняет ответ. Что не имеет значения на этом этапе, потому что сервер уже принял поддельный запрос и потратил мои деньги.

Ответ 3

Просто скромное завершение:

В: Политика единого происхождения (SOP) применяется только браузерами?
A: Да. Для всех вызовов, которые вы делаете внутри браузера, SOP определенно применяется браузером. Сервер может или не может проверить источник запроса.

Q: Если запрос не соответствует SOP, блокирует ли его браузер?
A: Нет, это вне полномочий браузеров. Браузеры просто отправляют запросы на разные источники и ждут ответа, чтобы проверить, правильно ли сервер озвучил вызов через заголовки Access-Control - *. Если сервер не отправляет обратно заголовок Access-Control-Allow-Origin, не отображает происхождение вызывающего абонента или не отправляет обратно заголовок * в заголовке, то все, что будет делать браузер, это воздерживаться от предоставления ответа вызывающему.

Q: Это значит, что я не могу подделать Origin?
A: В браузере и при использовании сценариев вы не можете переопределить Origin, как в контроле браузера. Однако, если вы хотите взломать себя, вы можете подделать вызовы, исходящие из ВАШЕГО браузера, используя расширения браузера или другие инструменты, установленные на вашем компьютере. Вы также можете выполнять вызовы HTTP, используя curl, Python, C# и т.д., И изменять заголовок Origin для серверов трюков.

Q: Итак, если я могу обмануть сервер, изменив Origin, значит ли это, что CORS небезопасен?
A: CORS, скажем так, ничего не говорит о безопасности - то есть аутентификации и авторизации запросов. Это до серверов, чтобы проверять запросы и аутентифицировать/авторизовать их любым механизмом, с которым они работают, таким как куки и заголовки. Сказав это, он может защитить нас немного больше в случае таких атак, как XSS:

Пример: Допустим, вы вошли на свой веб-сайт, и вредоносный скрипт пытается отправить запрос на веб-сайт вашего банка, чтобы узнать ваш баланс: атака отраженного XSS. Веб-сайт вашего банка доверяет учетным данным, поступающим (здесь от имени) вашего веб-сайта, поэтому запрос проходит проверку подлинности и выдается ответ HTTP, направленный на вредоносный код. Если веб-сайт вашего банка не заботится о совместном использовании его конечных точек с другими источниками, он не включает заголовок Access-Control-Allow-Origin в ответ. Теперь, по прибытии запроса, браузер понимает, что запрос был запросом перекрестного происхождения, но ответ не показывает, что сервер был рад поделиться ресурсом (здесь конечная точка запроса баланса) с вашим веб-сайтом. Таким образом, он нарушает поток, поэтому возвращаемый результат никогда не достигнет вредоносного кода.