Rails: как работает csrf_meta_tag?

Я разработчик PHP, изучающий Ruby on Rails, прочитав учебник Майкла Хартла. Вот цитата из книги, ссылаясь на csrf_meta_tag:

... метод Rails csrf_meta_tag [предотвращает] подделку межсайтовых запросов (CSRF), тип вредоносной веб-атаки. Не беспокойтесь о деталях (не волнуюсь); Просто знайте, что Rails усердно работает, чтобы обеспечить безопасность вашего приложения.

Дело в том, что мне действительно любопытно. Как работает вставка csrf-param а также csrf-token метатеги мешают CSRF? Я попробовал Google, но ничего не смог найти.

5 ответов

Решение

csrf_meta_tag в основном выполняет те же функции, что и скрытые поля формы, но позволяет отправлять запросы javascript, которые не привязаны к форме, для простого получения токена.

Если вы используете библиотеку jquery-ujs, содержимое этого метатега автоматически добавляется (как заголовок запроса) в любые выполненные запросы ajax.

csrf_meta_tag вставляет на страницу то, что по сути является цифровой подписью, и служит подтверждением того, что запросы, поступающие на сервер приложений, фактически поступают от правильно зарегистрированных пользователей. Это помогает предотвратить межсайтовый скриптинг (скрипт на совершенно не связанной странице запускает запросы, скажем, GMail, когда вы вошли в свой GMail на другой вкладке).

Я думаю, чтобы уточнить, csrf_meta_tag Само по себе это не препятствует тому, чтобы не связанная страница отправляла запросы на ваш GMail (или любой другой сервис, который является целью атаки), но "цифровая подпись" в csrf_meta_tag используется для проверки действительности указанных запросов. Недопустимые запросы (т. Е. От попыток межсайтового скриптинга) должны не пройти проверку и поэтому отбрасываются.

Проще говоря, с точки зрения атакующего:

До csrf_meta_tags Существующие (они не являются исключительными для Rails каким-либо образом), успешные атаки межсайтовых сценариев позволили вредоносному сайту передавать данные в веб-приложение таким образом, чтобы запрос выглядел так, как будто он выполняется от имени пользователя. Итак, допустим, вы являетесь администратором веб-службы, и на одной вкладке браузера вы вошли в панель администратора для этой службы. Если вредоносный сайт, открытый на другой вкладке, предназначался для вашей службы для атаки, он может запускать сценарии, которые отправляют запросы администратора, такие как удаление списка пользователей из базы данных, кража других конфиденциальных данных или потенциальный вред, повреждение, или уничтожение данных, содержащихся в сервисе, при этом все они (с точки зрения сервера) выглядят как действительные запросы от самого администратора. csrf_meta_tag это способ подписать запросы и помочь предотвратить такие попытки от успеха.

Здесь доступно гораздо более подробное объяснение.

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

В Rails это будет работать так

def csrf_meta_tags
    if protect_against_forgery?
      [
        tag('meta', :name => 'csrf-param', :content => request_forgery_protection_token),
        tag('meta', :name => 'csrf-token', :content => form_authenticity_token)
      ].join("\n").html_safe
    end
  end

Подробнее смотрите просто нажмите

Вам также необходимо проверить Руководство по безопасности Ruby On Rails

вот хороший блог

НО - я предпочитаю Национальную базу данных уязвимостей, вот хорошее объяснение

CWE-352: подделка межсайтовых запросов (CSRF)

CWE-79: неправильная нейтрализация ввода при генерации веб-страницы ("межсайтовый скриптинг")

Проверьте этот документ для CWE - Перечисление общей слабости

csrf_meta_tags являются указаниями для запросов ajax, чтобы использовать их в качестве одного из параметров формы для отправки запроса на сервер. Rails ожидает, что csrf будет частью вашего тела формы (params) для обработки ваших запросов. Используя эти метатеги, вы можете создать тело формы или заголовок csrf в соответствии с вашими потребностями. Я надеюсь, что этот ответ поможет вашему вопросу.

Вывод хелпера csrf_meta_tags:

<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="J/gw2ePXHS9Z1SUSSeUQgMmPhsPEFlFbMrLTLFHLfKjeWh7g4uyOnBlfKnlZlmCBiALDWdDWCSo1z0tybGVtfA==" />

Этот токен может быть включен в запрос ajax. Пример ( jquery-ujs):

https://github.com/rails/jquery-ujs/blob/4b6e30f68ff1244fc0c790641d3408c2695a29bd/src/rails.js#L70

    csrfToken: function() {
     return $('meta[name=csrf-token]').attr('content');
    },

    // URL param that must contain the CSRF token
    csrfParam: function() {
     return $('meta[name=csrf-param]').attr('content');
    },

    // Make sure that every Ajax request sends the CSRF token
    CSRFProtection: function(xhr) {
      var token = rails.csrfToken();
      if (token) xhr.setRequestHeader('X-CSRF-Token', token);
    },
Другие вопросы по тегам