Rails 3: Getting CSRF Warning even though authenticity_token exists - ruby-on-rails

On multiple parts of my site I'm receiving WARNING: Can't verify CSRF token authenticity in my log file, which is resetting my sessions. However, I have the authenticity tokens:
Started POST "/check_out/shopping_cart_with_authenticated_user" for 10.189.254.5 at 2013-09-12 11:19:02 -0400
Processing by CheckOutController#shopping_cart_with_authenticated_user as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"rGcLQAR/s7zRNf2WEqkuD7ar8IXs0alt7szJKSfgLio="}
SESSION VARIABLES ARE: {}
WARNING: Can't verify CSRF token authenticity
and here:
Processing by SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"N1F53oN1fTv2Ysg/27biH14dDyTtkm2RinAUqSHwGAs=", "user"=>{"email"=>"liz#nsdfsdfsdfsry.com", "password"=>"[FILTERED]"}, "commit"=>"Sign in"}
SESSION VARIABLES ARE: {"current_cart_id"=>55175183, "_csrf_token"=>"HzPm7DHLslbV76wJ3ahCqPkOO4bv5k5CkjKBe3C9WHE=", "flash"=>#<ActionDispatch::Flash::FlashHash:0x00000005f1e028 #used=#<Set: {}>, #closed=false, #flashes={}, #now=#<ActionDispatch::Flash::FlashNow:0x00000005e81570 #flash=#<ActionDispatch::Flash::FlashHash:0x00000005f1e028 ...>>>, "warden.user.user.key"=>["User", [358060], "$2a$12$VcSeYjhwx6JkgERnlN0clu"], "logged_in_by_password"=>true, "user_id"=>358060}
WARNING: Can't verify CSRF token authenticity
What's the deal? I'm using Rails generated forms. Here's an example of a Devise form I'm using:
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
<%= token_tag form_authenticity_token %>
<div class="formField"><label for="email">Email <span>example: jane#example.com</span></label>
<%= f.email_field :email, :autofocus => true, :id => "email", :class => "textfield col" %></div>
<div class="formField"><label for="password">Password <span>is cAsE sEnSiTiVe</span></label>
<%= f.password_field :password, :class => "textfield col" %></div>
<div><%= f.submit "Sign in", :disable_with => "Signing in…".html_safe,:id => 'log_in', :class => 'button-red-shiny full-width ' %></div>
<% end %>
== UPDATE ==
So eventually I closed the browser and reopened it and it worked again... But it bothers me that this has happened on multiple occasions. Anyone know how I could prevent it from occurring again?

Your CSRF token isn't being matched between the client and the server. This causes this error to occur.

Related

Ruby Blog Tutorial - ActionController::InvalidAuthenticityToken

I am completing the Ruby Rails tutorial for a blog and when I try and submit a new post I am getting a ActionController::InvalidAuthenticityToken error from the browser.
I am new to Ruby Rails (hence why I am doing the tutorial) and I have been back through the examples and have looked a various other answers etc and I cannot seem to find what the problem could be? I would like to understand the problem and how to fix it as part of learning.
This is what is shown in the extracted source :
def handle_unverified_request
raise ActionController::InvalidAuthenticityToken
end
end
end
This is from the Server :
Parameters: {"authenticity_token"=>"MijxdOhNKeov89oetl7Xa0KWpSZoeb3WAIuX0RECyIusjfjs/B5megtnH6JFOSG1G5K7g+csApABCn31UxdYGg==", "article"=>{"title"=>"po request"
, "text"=>"I want to buy some cheese"}, "commit"=>"Save Article"}
HTTP Origin header (https://3000-dot-4708054-dot-devshell.appspot.com) didn't match request.base_url (https://127.0.0.1:3000)
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 499)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
And this is the .erb for a new record:
<%= form_with scope: :article, url: articles_path, local: true do |form|
%>
<% end %>
<%= link_to 'Back', articles_path %>
<%= form_with scope: :article, url: articles_path, local: true do |form|
%>
<p>
<%= form.label :title %><br>
<%= form.text_field :title %>
</p>
<p>
<%= form.label :text %><br>
<%= form.text_area :text %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
The authenticity token is used by rails to ensure that requests come from the site rails is expecting. When it generates a form, it includes the verification token for this purpose. There's a much better explanation of the history / why it's used here:
Understanding the Rails Authenticity Token
If you want to keep the checks in, then the short answer is to include
<%= form_authenticity_token %>
In any views that generate forms. This will ensure the correct token is in the form, and prevent the error from occuring

Password not filtered in log

According to Rails documentation
config.filter_parameters used for filtering out the parameters that
you don't want shown in the logs, such as passwords or credit card
numbers. By default, Rails filters out passwords by adding
Rails.application.config.filter_parameters += [:password] in
config/initializers/filter_parameter_logging.rb. Parameters filter
works by partial matching regular expression.
So, why when I submit the form below
<%= form_with model: #user, url: admin_user_path, method: :delete do %>
<%= label_tag :password, t('forms.password') %>
<%= text_field_tag :password, nil %>
<%= button_tag t('forms.save'), type: 'submit' %>
<% end %>
I can see my password in the log?
<ActionController::Parameters {"utf8"=>"✓", "_method"=>"delete", "authenticity_token"=>"r22P2Mi1xcWOjRHGogoFaDcOec9/FgkC9btCo66qmqaKG/zwzUkbUGtATsTKV19OOYK80VBf1h0CzFtoRltQOA==", "password"=>"x", "button"=>"", "controller"=>"admin/users", "action"=>"destroy", "id"=>"at-example-com"} permitted: false>
Shouldn't the password be [FILTERED]?
The piece of code you're showing isn't from a log:
<ActionController::Parameters {"utf8"=>"✓", "_method"=>"delete", "authenticity_token"=>"r22P2Mi1xcWOjRHGogoFaDcOec9/FgkC9btCo66qmqaKG/zwzUkbUGtATsTKV19OOYK80VBf1h0CzFtoRltQOA==", "password"=>"x", "button"=>"", "controller"=>"admin/users", "action"=>"destroy", "id"=>"at-example-com"} permitted: false>
That output from the command like puts(params). The option filter_parameters is about log file which placed under log directory. E.g. log/development.log
Here is a piece of log file:
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"mxQJeccoEATtyCFy1eV", "user"=>{"first_name"=>"Juggy Head", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create user"}
You have used text_field_tag (It's going to input type text) that's why it's showing value in the log you need to use password_field_tag (It's going to input type password) like below
<%= form_with model: #user, url: admin_user_path, method: :delete do %>
<%= label_tag :password, t('forms.password') %>
<%= password_field_tag :password, nil %>
<%= button_tag t('forms.save'), type: 'submit' %>
<% end %>
Rails API doc here
For instance, password filtering to use above code
Update
I completely agree with this answer Зелёный

rails form helper password security issue

This is the font-code.
<%= form_for(:something, :html=> {:id => 'login'}, :url => 'login/create') do |form| %>
<h1>Log In</h1>
<fieldset id="inputs">
<%= form.text_field :username, :placeholder => 'Username', :autofocus=>true%>
<%= password_field_tag(:password, :placeholder => 'Password') %>
<%= password_field_tag :userpass1, placeholder: 'Password'%>
<%= password_field_tag :userpass, params[:userpass], placeholder: 'Password', class: 'input-small'%>
</fieldset>
<fieldset id="actions">
<input type="submit" id="submit" value="Log in">
Register
</fieldset>
<%end%>
and if i submit, it sends like this,
Processing by LoginController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"2RQKkdOZf2HL+dsY2peWYUIaY78WBZBvNveKKBvZv60=", "something"=>{"username
"=>"test"}, "password"=>"[FILTERED]", "userpass1"=>"test2", "userpass"=>"est3"}
in here, the first password field is sending with filtered, but the other two are just showing what the user typed.
what is the problem?
and the most big problem is, after i send this and check the request header,
it shows all the parameter, even the data what have been filetered like this,
Any good solution about this?!
You probably have line
config.filter_parameters += [:password]
in your config/application.rb. Modify it to:
config.filter_parameters += [:password, :userpass, :userpass1, :userpass2]
That causes filtering additional parameters in logs.
The second "problem" is not a problem at all. How do you suppose server to know what your parameters are if you want to filter them in request?

Devise forgot password throws ArgumentError in Devise::PasswordsController#create

Initially, I was having this issue only on my heroku app, but after updating the devise gem to 2.2.4, I have the issue on my localhost as well.
My main concern is that I am getting this error:
ArgumentError (wrong number of arguments (2 for 1)):
app/mailers/user_mailer.rb:58:in `reset_password_instructions'
I've updated the devise gem to
devise (2.2.4)
And I am running:
Rails 3.2.11
My development.rb initializer has the following host:
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
This is where line 58 starts in my user_mailer.rb file:
def reset_password_instructions(user)
devise_mail(user, :reset_password_instructions)
end
My question is, why am I sending two arguments? It should only be sending in the e-mail address as defined in my devise/passwords/new.html.erb file:
<div class="container">
<%= form_for(resource, :html => {:class => "form-signin", :method => :post}, :as => resource_name, :url => password_path(resource_name)) do |f| %>
<h2 class = "form-signin-heading">Forgot your password?</h2>
<%= devise_error_messages! %>
<%= f.email_field :email, :type => "text", :class =>"input-block-level", :placeholder => "Email Address" %>
<%= f.submit "Send me reset password instructions", :class => "btn btn-large btn-primary" %>
</br>
</br>
<%= render "devise/shared/links" %>
<% end %>
</div>
EDIT:
My reset_password_instructions.html.erb file is here:
<p>Hello <%= #resource.email %>!</p>
<p>Someone has requested a link to change your password, and you can do this through the link below.</p>
<p><%= link_to 'Change my password', edit_password_url(#resource, :reset_password_token =>#resource.reset_password_token) %></p>
<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>
Can anyone spot an issue?
It looks like the answer was quite simple, I had to follow the upgrading instructions from devise. For anyone running into this problem, the upgrade to Devise 2.2 can be found on Devise 2.2 upgrade instructions
Edit:
The upgrade documentation for Devise includes instructions to modify methods with an options block. To fix this issue you need to re-define the reset_password_instructions method as follows (note, the default is to use record in place of user but this specific example uses user):
def reset_password_instructions(user, opts={})
...
end

Routing issue. Url becomes parameter

I have a url with path /user_management/edit_official/:id
its corresponding output from rake routes is
user_management_update_official POST /user_management/edit_official/:id(.:format) {:controller=>"user_management/employees", :action=>"update_official"}
When I try to access url via form, url is not reached, because the url /user_management/edit_official/:id becomes a parameter.
Following is the log file entry?
Started POST "/user_management/edit_official/31" for 127.0.0.1 at
2012-01-02 11:05:21 +0530 Processing by ErrorsController#index as
HTML
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"DED4E/9w/GDUQdjZ27mrUWrYBgipgHnNvS8mOjdaNXU=",
"employee"=>{"empl_id"=>"", "confirmation_date"=>"",
"designation_id"=>"", "rep_head1_id"=>"", "payment_mode"=>"",
"pf_number"=>"", "bank_name"=>"", "pt_applicable"=>"false",
"reg_date"=>"", "employee_type_id"=>"", "joining_date"=>"",
"rep_head2_id"=>"", "pf_applicable"=>"false",
"bank_account_number"=>"", "empl_email_id"=>"false",
"last_working_date"=>""}, "designation_level"=>"L-5b",
"user"=>{"username"=>"dsaf.adsfas", "password"=>"[FILTERED]"},
"commit"=>"Next", "a"=>"user_management/edit_official/31"}
Is there any reason for this. Thanks.
EDIT: Form included
<% url = user_management_update_official_path(#employee) %>
<%= form_for(#employee, :url => url, :html => { :enctype => 'multipart/form-data'} ) do |f| %>
<div id="employee_details" class="employee_form_steps">
<%= render :partial => 'user_management/employees/official_information',
:locals => { :f => f} %>
</div>
<div class="btn_row">
<%= content_tag(:button, '< Back', :id => 'official_information_back', :class => 'grey') %>
<%= f.submit 'Next', :class => 'green', :style => 'margin:0px;padding:4px;width:50px;' %>
<%= content_tag(:button, 'Cancel', :class => 'cancel grey') %>
</div>
<% end %>
The error must lie in your routes.rb
The rule in this file is: first match, first served.
Try to take the line corresponding to "errors#index" and put it under the one describing /user_management/edit_official/:id
The actual problem was the http method used for form. The form_for used put method while, in routes I specified POST. Changing POST to PUT, made everything work.

Resources