Как передать токен CSRF между приложениями rails

В нашем приложении rails3 говорится о другом приложении rails, которое отображается как функции REST. Мы получаем следующую миграцию предупреждения на rails3 во всех вызовах POST, сделанных службам REST.

WARNING: Can't verify CSRF token authenticity

Как мы должны передавать токен csrf на провод, когда мы делаем запрос POST для служб REST, метод ApplicationController имеет метод protect_from_forgery, и вызов также распространяется на вызов handle_unverified_request. Мы используем HTTP basic auth для аутентификации, и, похоже, он работает нормально. Что мы должны сделать для решения этой проблемы.

Ответ 1

Хорошо, теперь я дам ему шанс ответить на ваш вопрос.

Тоны CSRF "зависят от сеанса", это означает, что пользователь должен поделиться сеансом с приложением, с которым он взаимодействует. Это означает, что запрос должен быть сделан до того, как он представит фактическую форму, которая соответствует стандартным форматам HTML, где форма отображается до ее отправки, чтобы там было место для создания токена CSRF для этого пользователя.

Позвоните в приложение, которое служит для кнопки UI Button App1, и для одного из них, где находится приложение REST Service App2.

Пользователь делится сеансом с App1 и получает кнопку пользовательского интерфейса, обслуживаемую App1. Как только пользователь нажимает кнопку, выполняется запрос к App1, а App1 отправляет запрос в службу REST App2.

Заключение: пользователь не использует сеанс с App2, но ваш App1 имеет сеанс с App2. Это завершается двумя вещами:

  • Пользователь не уязвим для Cross-Site-Forgery на App2, потому что у него нет сеанса на этом сервере. Поэтому, если я разместил что-то вроде <img src="http://app2.com/rest-service/destroy> здесь, App2 не узнал бы меня, потому что я не делюсь сеансом с App2, и ничего не происходит.

  • Вы можете реализовать свои собственные меры безопасности в службе REST, чтобы защитить их от общественности:

    • Аутентификация по HTTP Basic Auth
    • Аутентификация с помощью ключа API
    • ....

Это означает, что вы можете отказаться от защиты CSRF в службе REST и оставаться на безопасной стороне, пока пользователь не может совершать прямые вызовы через AJAX и т.д.

Добавление

CSRF защищает ваш сайт от представленных форм, которые не поступают из вашего источника (на самом деле это относится к формам POSTed только потому, что они обычно управляют данными.

Большой сценарий: я атакующий, и я хотел бы обновить имя вашей учетной записи пользователя до "Mr. Potatoe", как я бы это сделал, чтобы разместить скрытую форму на моем веб-сайте, которая получает POSTED Yourdomain.com/account со скрытым полем, например account[name]="Mr. Potatoe". Теперь, что происходит без защиты CSRF? Мой браузер отправляет форму и отправляет ей cookie аутентификации, и мое имя теперь "Mr. Potatoe". Что происходит с защитой CSRF? Мои браузеры отправляют форму и отправляют файл cookie, но форма не имеет токена CSRF, поэтому запрос отклоняется. Теперь есть ли способ атаковать, чтобы получить токен CSRF в этих обстоятельствах? Ответ - нет. Может быть, вы спросите себя....

  • Что делать, если я помещаю скрытый iframe на свой сайт, который указывает на Yourdomain.com/account/edit, и просто скопируйте скрытое поле, содержащее токен? - Ответ: он не будет работать из-за той же политики происхождения, вы не можете прочитать, что внутри iframe, если его содержимое не поступает из вашего домена.

  • Что делать, если я делаю вызов AJAX в фоновом режиме, чтобы получить токен? Ответ: Это не сработает, потому что, используя чистый AJAX, вы также связаны с той же политикой происхождения.

Теперь давайте перейти к точке: я не могу отправить скрытый вызов AJAX с моей страницы на ваш, чтобы нанести вред вашему пользователю, который находится на моем сайте.

Что это значит? Вы можете реализовать фильтр before, который проверяет, является ли значение request.xhr? истинным, или пользовательский агент является чем-то вроде "My REST Client XY", потому что это невозможно подделать с помощью запроса на кросс-сайт в браузере → lt. Поэтому, если это так, вы можете игнорировать/отключать защиту CSRF.

Кстати, если вы хотите сделать запрос AJAX на своем сайте, вы можете получить токен CSRF следующим образом:

var token = $('meta[name="csrf-token"]').attr('content');

См. Rails UJS Script: https://github.com/rails/jquery-ujs/blob/master/src/rails.js#L81

ПРИМЕЧАНИЕ: это только защищает вас от подделки подделок и ничего другого....