может отправлять форму много раз с одним и тем же токеном csrf

#ruby-on-rails #ruby-on-rails-4 #form-for #csrf-protection

#ruby-on-rails #ruby-on-rails-4 #форма- для #csrf-защита

Вопрос:

В моем приложении у меня есть форма для создания города.

Все работает нормально, когда для параметра remote в форме установлено значение false. Однако возникает проблема, когда я меняю его на true.

Когда форма отправляется удаленно, я могу отправить две формы с одним и тем же токеном CSRF и вместо получения ошибки ActionController::InvalidAuthenticityToken для второго запроса. Вторые запросы также создадут объект, чего не должно быть.

Знаете ли вы, что вызывает эту проблему и как я могу ее исправить?

 <%= form_for [:administrators,@city],remote: true,:authenticity_token => true do |f| %>
<div class="field">

    <%= f.label :province_id,'Select a province' %>
    <%= f.select :province_id,options_from_collection_for_select(Province.all, :id,:name, @city.province_id),{ :prompt => 'Select province' } %> <br>
    <div class="errors alert-box alert" style="display:none;"></div>
</div>
<div class="field">
    <%= f.label :name %>
    <%= f.text_field :name%> 
    <div class="errors alert-box alert" style="display:none;"></div>
</div>
<div class="action">
    <% if @city.id? %>
        <%= f.submit 'Update', class:'button' %>
        <btn class='cancel_form_button button tiny alert'>  </btn>
    <% else %>
        <%= f.submit 'Create', class:'button' %>
    <% end %>
</div>
  

Комментарии:

1. Запросы поступают из вашего кода, и они являются аутентичными. Таким образом, токен выполняет свое обещание. Это не обещает защитить вас от повторных запросов, не так ли?

2. @SergioTulentsev если вы установите для remote значение false, а затем попытаетесь отправить форму во второй раз, вы получите сообщение об ошибке ActionController::InvalidAuthenticityToken

3. Как отправить форму во второй раз, если страница перезагружается?

4. Кроме того, вы проверили сгенерированную форму? есть ли скрытое поле токена в удаленной форме?

5. @SergioTulentsev используя инструмент разработчика FireFox, вы можете редактировать и повторно отправлять запрос. да, токен включен.

Ответ №1:

Правильно ли я понимаю, что вы хотите предотвратить создание city с теми же параметрами?

Тогда это не ответственность за токен CSRF. CSRF предотвращает запросы от других доменов к вашему серверу, это функция безопасности.

Проверка данных (допуск только одного города с некоторыми конкретными параметрами) является обязанностью по проверке модели. Поэтому вам нужно будет добавить validates_uniqueness_of :name в свою City модель. (также вы можете добавить scope: :province_id опцию). Смотрите http://guides.rubyonrails.org/active_record_validations.html#uniqueness

С другой стороны, если вы просто хотите запретить пользователю время от времени дважды щелкать по отправке, вы можете добавить disable_with опцию в btn helper, чтобы отключить ее после щелчка (вам нужно будет включить ее обратно в своем коде после ответа)

Комментарии:

1. нет, это не то, что я имел в виду. Я думаю, вы не должны иметь возможности отправлять две формы с одним и тем же токеном CSRF, что возможно в этой ситуации, но невозможно, когда форма не отправляется удаленно.

2. что происходит, когда вы отправляете форму синхронно?

3. Когда я отправляю форму синхронно, если я попытаюсь отправить форму во второй раз с тем же токеном, я получу ошибку InvalidAuthenticityToken