Какой смысл в заголовке X-Requested-With?

224

JQuery и другие фреймворки добавляют следующий заголовок:

X-Requested-With: XMLHttpRequest

Зачем это нужно? Почему сервер хочет обрабатывать запросы AJAX иначе, чем обычные запросы?

ОБНОВЛЕНИЕ : я только что нашел реальный пример, используя этот заголовок: https://core.spreedly.com/manual/payment-methods/adding-with-js . Если обработчик платежей запрашивается без AJAX, он будет перенаправлен обратно на исходный веб-сайт, когда это будет сделано. Когда это запрашивается с помощью AJAX, перенаправление не выполняется.

Гили
источник
7
«[Когда] запрашивается без AJAX, он перенаправляет обратно на исходный веб-сайт, когда это сделано. Когда его запрашивают с AJAX, перенаправление не выполняется». -> Именно поэтому вы хотели бы сделать это. :)
Роберт Кристиан
1
stackoverflow.com/questions/3315914/…
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功

Ответы:

258

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

Только следующие заголовки разрешены для междоменного домена:

  • принимать
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Тип содержимого

любые другие приводят к тому, что в браузерах с поддержкой CORS выдается запрос «перед полетом».

Без CORS невозможно добавить X-Requested-Withк междоменному запросу XHR.

Если сервер проверяет наличие этого заголовка, он знает, что запрос не был инициирован из домена злоумышленника, пытающегося сделать запрос от имени пользователя с JavaScript. Это также проверяет, что запрос не был отправлен из обычной HTML-формы, из которой сложнее проверить, что он не является междоменным без использования токенов. (Однако проверка Originзаголовка может быть вариантом в поддерживаемых браузерах, хотя старые браузеры останутся уязвимыми .)

Обнаружен новый обход Flash

Возможно, вы захотите объединить это с токеном , потому что Flash, работающий в Safari на OSX, может установить этот заголовок, если есть шаг перенаправления . Похоже, он также работал на Chrome , но теперь исправлен. Более подробная информация здесь, включая различные версии затронуты.

OWASP Рекомендуем сочетать это с проверкой происхождения и реферирования :

Эта техника защиты специально обсуждается в разделе 4.3 «Надежная защита для подделки межсайтовых запросов». Однако обходные пути этой защиты с использованием Flash были задокументированы еще в 2008 году, а затем еще в 2015 году Матиасом Карлссоном, чтобы использовать уязвимость CSRF в Vimeo. Но мы считаем, что атака Flash не может подделать заголовки Origin или Referer, поэтому, проверяя их обе, мы полагаем, что эта комбинация проверок должна предотвратить обход Flash CSRF-атак. (ПРИМЕЧАНИЕ. Если кто-либо может подтвердить или опровергнуть это мнение, пожалуйста, сообщите нам об этом, чтобы мы могли обновить эту статью)

Однако по причинам, которые уже обсуждались, проверка Origin может быть сложной.

Обновить

Написано более подробно в блоге о CORS, CSRF и X-Requested-With здесь .

SilverlightFox
источник
14
Я не понимаю Что мешает злоумышленнику создать запрос и добавить X-Requested-Withзаголовок?
Грег
13
@Greg: браузер - он не разрешает междоменный.
SilverlightFox
2
О, я не знал, что конфигурация CORS не понадобится, если вы находитесь в одном домене. Это очевидно, хотя, когда вы думаете об этом. Спасибо !
Грег
10
@ vol7ron: Ничто не останавливает их, но тогда у них не будет печенья их жертвы в запросе, который побеждает объект их выполнения. Для успешного выполнения CSRF злоумышленнику потребуется браузер, который автоматически прикрепляет файлы cookie с запросом, поэтому без использования браузера атака CSRF невозможна.
SilverlightFox
3
@ vol7ron: бывший. CSRF - запутанная депутатская проблема. Браузер - запутанный заместитель и «обманут», отправляя куки-файлы для запроса, который пользователь не сделал самостоятельно.
SilverlightFox
25

Обязательно прочитайте ответ SilverlightFox. Это подчеркивает более важную причину.

Причина в основном в том, что если вы знаете источник запроса, вы можете немного его настроить.

Например, допустим, у вас есть веб-сайт с множеством рецептов. И вы используете пользовательский каркас jQuery для перемещения рецептов в контейнер на основе ссылки, по которой они щелкают. Ссылка может бытьwww.example.com/recipe/apple_pie

Теперь обычно возвращается полная страница, верхний и нижний колонтитулы, содержимое рецепта и реклама. Но если кто-то просматривает ваш сайт, некоторые из этих частей уже загружены. Таким образом, вы можете использовать AJAX, чтобы получить рецепт, выбранный пользователем, но для экономии времени и пропускной способности не загружайте верхний / нижний колонтитулы / рекламные объявления.

Теперь вы можете просто написать вторичную конечную точку для таких данных, как, www.example.com/recipe_only/apple_pieно это сложнее поддерживать и делиться с другими людьми.

Но проще просто обнаружить, что это ajax-запрос, выполняющий запрос и возвращающий только часть данных. Таким образом, пользователь тратит меньше трафика и сайт выглядит более отзывчивым.

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

На самом деле это похоже на Accept-Languageзаголовок. Браузер может запросить веб-сайт. Пожалуйста, покажите мне русскую версию этого веб-сайта без необходимости вставлять / ru / или аналогичный в URL.

EWit
источник
30
Вау, это звучит как ужасный кошмар обслуживания. Если вы хотите вернуть другое представление одной и той же страницы, вы должны предоставить другой тип контента для Acceptзаголовка. Использование собственного заголовка для этого звучит как неправильный путь.
Гили
10

Некоторые платформы используют этот заголовок для обнаружения запросов xhr, например, безопасность Grails Spring использует этот заголовок, чтобы идентифицировать запрос xhr и давать ответ json или ответ html в качестве ответа.

Большинство библиотек Ajax (Prototype, JQuery и Dojo начиная с версии 2.1) содержат заголовок X-Requested-With, который указывает, что запрос был сделан XMLHttpRequest, а не вызван нажатием обычной гиперссылки или кнопки отправки формы.

Источник: http://grails-plugins.github.io/grails-spring-security-core/guide/helperClasses.html

Корай Гюклю
источник