CSRF из библиотеки JS в Rails

Моя задача — написать функцию в пакете javascript, которая будет встроена в html-сайты для проверки формы. Проверка будет выполняться через вызов API на мой сервер.

Вопрос в том, как передать и проверить токен CSRF с JS на мой сервер Rails.

Я пытался сделать это:

var token = function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))};

$.ajax({
    url: 'http://localhost:3000/csrf-check',
    type: 'POST',
    beforeSend: token,
    data: {
        hey: 'hey'
    },
    success: function(response) {
        console.log(response);
    }
})

В моем ValidatorController:

class ValidatorController < ApplicationController
  protect_from_forgery

  def csrf_check
    if session[:_csrf_token]
      render json: :ok
    else
      render json: :fail
    end
  end
end

Как я могу отправить токен CSRF и проверить его на сервере Rails?


person RomanOks    schedule 27.07.2020    source источник


Ответы (2)


Прежде всего: я не очень понимаю, зачем вам это нужно — см. комментарий max.

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

class CsrfTokenChecksController < ApplicationController
  skip_forgery_protection

  def show
    head any_authenticity_token_valid? ? :ok : :bad_request
  end
end

При этом используется метод any_authenticity_token_valid? (см. https://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html#method-i-any_authenticity_token_valid-3F), который используется внутри Rails как часть его фильтра защиты от подделки.

Примечание. Этот метод существует с Rails 5. Если вы используете Rails 4, вместо этого вам придется использовать valid_authenticity_token?(session, request.headers['X-CSRF-Token']). Для Rails 3 это будет form_authenticity_token == request.headers['X-CSRF-Token'].

person Clemens Kofler    schedule 27.07.2020

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

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

На самом деле это работает только в том случае, когда Rails фактически отображает HTML, поскольку он просто дает гарантию, что запрос исходит с того же сервера, который отрисовывал форму.

Если вы намеренно делаете что-то кросс-сайтовое, это просто не сработает и даже не принесет никакой пользы. Существуют и другие механизмы, такие как ключи API, которые можно использовать для проверки законности запроса.

person max    schedule 27.07.2020
comment
stackoverflow.com/questions/35181340/ - person max; 27.07.2020