Что мешает вредоносному коду подменить заголовок «Origin» для использования CORS?

142

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

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

Джей Ламонт
источник
2
Я считаю, что дело в том, что исходный домен, из которого обслуживается страница (здесь foo.com), должен предоставлять Access-Control-Allow-Originзаголовок, иначе браузер не разрешит запрос bar.com.
Chris Hayes
2
Чтение этого сообщения действительно помогло мне понять процесс cors между браузером, исходным и целевым сервером. html5rocks.com/en/tutorials/cors
brendonparker
5
@ChrisHayes CORS работает совсем не так. Вы можете прочитать об этом немного больше, просмотрев спецификацию или эту замечательную вики-страницу MDN по этой теме .
Ray Nicholus
1
@brendonparker Да, это отличная статья. Этот автор отвечает на множество вопросов CORS по SO, а также поддерживает enable-cors.org .
Ray Nicholus
4
@RayNicholus Интересно, я был явно далеко. Спасибо за ссылки. Судя по голосам по моему комментарию, не только я страдаю от этого заблуждения. Я надеюсь, что эти двое вернутся и научатся (и уберут свои голоса!).
Chris Hayes

Ответы:

149

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

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

мосье
источник
3
Это имеет большой смысл. Если браузер не позволяет JavaScript переопределять заголовок Origin, проблем нет. Если вы выполняете запросы извне браузера, у вас не будет файлов cookie. Думаю, я был сбит с толку, потому что во всех документах, которые я читал, нигде не говорилось явно, что заголовок Origin не может быть переопределен. Спасибо!
Джей Ламонт
41
Если кто-то хочет что-то подделать, он может это сделать. Используя практически любой язык сценариев, они могут создавать HTTP-запросы. В Perl и Python есть http-библиотеки, которые упрощают эту задачу. Библиотеки хранят и отправляют файлы cookie, позволяют добавлять произвольные заголовки и предоставляют много отладочной информации. Таким образом, заголовки CORS предназначены только для того, чтобы вредоносному javascript на форуме, который вы читаете, было сложнее сделать что-то неприятное с вашим банковским счетом в другом домене, когда вы вошли в оба в своем браузере.
Mnebuerquo
9
И чтобы прояснить, злоумышленник мог просто создать экземпляр браузера, который был пропатчен, чтобы позволить им вручную управлять заголовком Origin, а затем полностью выдать себя за обычного пользователя, куки, AJAX и все остальное.
Джордан Ригер
10
«Браузеры контролируют настройку заголовка Origin, и пользователь не может изменить это значение». Я уверен, что очень легко использовать такой инструмент, как Fiddler2 или Charles, для изменения заголовков, когда запрос покидает браузер.
Asa
3
злоумышленник может просто создать экземпляр браузера, который был пропатчен, чтобы позволить им вручную управлять заголовком Origin. Если у вас есть доступ к машине до такой степени, что вы можете «просто создать пропатченный экземпляр браузера» (на самом деле звучит не так просто мне), почему бы просто не читать файлы cookie напрямую с диска? Как вы знаете, они хранятся в виде обычного текста. В реальной жизни межсайтовый скриптинг представляет собой реальную угрозу, в то время как ваш сценарий атаки просто надуман и непрактичен.
Stijn de Witt
35

TL; DR: ничто не мешает вредоносному коду подменить источник. Когда это произойдет, ваш сервер никогда не узнает об этом и будет действовать в соответствии с запросами. Иногда эти запросы обходятся дорого. Так что не используйте CORS вместо любого типа безопасности.


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

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

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

Затем я подделал Originзаголовок клиента 2, чтобы он соответствовал заголовку клиента 1. Сервер получил поддельный Originзаголовок и успешно прошел проверку белого списка (или провалился, если вы парень наполовину пустой). После этого Сервер работал послушно, потребляя все ресурсы, которые он был предназначен для потребления (вызовы базы данных, отправка дорогих электронных писем, отправка еще более дорогих SMS-сообщений и т. Д.). Когда это было сделано, сервер успешно отправил 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и правильно отклоняет ответ. На данный момент это не имеет значения, потому что сервер уже принял поддельный запрос и потратил мои деньги.

Nocturno
источник
2
@Nocturno, спасибо за пример. Позвольте мне просто добавить свое наблюдение. CORS относится к функциям безопасности браузера. Если безопасный браузер изменен из своего первоначального состояния, это может быть интерпретировано как в браузере, возможно, отсутствует функция безопасности.
Лука
10
Совсем не гениально. Это полностью упускает суть CORS. Если вы в состоянии перехватывать запросы, исходящие с машины пользователя, вы можете просто прочитать их куки, установить кейлоггеры, вирусы и все эти другие реальные угрозы. CORS предназначен для защиты честных пользователей, вошедших на сайт A, от вредоносного сценария, который каким-то образом был внедрен на сайт B. Сценарий на сайте B (который может быть фрагментом Javascript в сообщении на форуме, которое не было правильно экранировано сайтом B) выполняет действия на сайте A под учетной записью пользователя (например, удаление материалов и т. д.) с использованием файла cookie сеанса с сайта A.
Stijn de Witt
3
Это называется межсайтовым скриптингом, и без CORS его можно было бы сделать без необходимости получать контроль над машиной пользователя. В этом весь смысл. Никакого контроля над машиной пользователя не требовалось, потому что при выполнении запросов к сайту A браузер автоматически добавлял файл cookie сеанса в запрос, поэтому он выглядел как действительный запрос от самого пользователя, хотя на самом деле он исходил из сценария на каком-то другом сайт. Политика одинакового происхождения предотвращает это, и CORS используется для внесения в белый список доменов, которым должен быть предоставлен доступ, даже если они находятся в другом источнике.
Stijn de Witt
3
@Nocturno Да, я был немного грубоват, извините за это. Ваша исходная точка зрения остается в силе. Политика Same-Origin - это функция безопасности браузера, а CORS - это механизм для ослабления этой безопасности путем внесения некоторых доменов в белый список. OP должен понимать, что подмена заголовка Origin нецелесообразна в качестве «атаки», поскольку не приносит вам ничего, чего нельзя было бы получить, например, с помощью curl.
Stijn de Witt
3
@Nocturno Я думаю, что ваше вступительное заявление немного вводит в заблуждение. There's nothing stopping malicious code from spoofing the origin-> Да, есть, javascript не может быть установлен Origin. Да, пользователь может изменить свой браузер / использовать скрипт для изменения происхождения, но CORS защищает не от этого; Веб-сайты, контролируемые злоумышленником, не могут изменить Origin, вот и все.
RJFalconer 07
13

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

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

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

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

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

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

Алиреза
источник
Красиво, лучше / яснее, чем принятый ответ ИМО
3dGrabber