AJAX call log out my account - ruby-on-rails

I have a Rails 3 app and I am using Warden for authentication.
It works fine but when I try to use AJAX(POST) access one of the controller the application log out my account and ask me to log in again.

This is because of the rails CSRF token validation. There are a few different ways to deal with this:
Hacky, dirty shortcut - just make the AJAX call use HTTP GET instead of POST. GET will not look for CSRF token by default
Another dirty shortcut - turn off CSRF validation for this particular action in your controller
protect_from_forgery :except => :create
Properly implement CSRF token with AJAX calls, there are many guides out there, for example this one or this one

Related

How to bypass csrf token check in Rails to be able to test request using API?

I started working on a Rails project, where it's not only API app, so it used CSRF verifications for each request. However, requests return JSON and could be theoretically tested using Postman (or similar Http client). The only thing that gets in the way in csrf token validation.
The only way that enabled me to bypass it is adding skip_before_filter for certain actions (temporarily for testing):
skip_before_action :verify_authenticity_token, only: %i[action_name]
Is there anyway to bypass this check with using special headers/credentials?
Cookie is fine, I copied it from UI request. However, CSRF cannot be copied since it is different for each request.
Thanks in advance

How to solve invalid authenticity token error in Rails when sending form data from external page

I have a WordPress page that I built before I learned Rails. On the page there is a form. I want to send the form data to a Rails route. But i get an invalid authenticity token error. How do I satisfy rails with an authenticity token since I understand that they are created by the Rails app itself and therefore would never exist outside of Rails?
Since this sounds like a separate app that you want to use to post data to a rails endpoint, you probably don't care about CSRF issues for the controller action that handles this. You could disable the authenticity token verification for your controller action with:
# inside your controller class
skip_before_action :verify_authenticity_token, only: [:your_wordpress_action]

Turn on request forgery protection with or witout Rails's protect_from_forgery?

I building a REST API based on Rails 4.
To prevent from cross-site request forgery attacks, I added a CSRF token inside a custom HTTP header that is needed to perform requests such as POST, DELETE, etc.
I know Rails 4 also provides a protect_from_forgery method with a special option for APIs: with: :null_session.
So I think that, given it's a best practice, this new Rails method should be present at the top of my ApplicationController.
But in the same time, I'm also wondering why I should add it... if it is not necessary. Because as I said, my requiring a CSRF token inside a custom HTTP header.
Could you give me the benefits of adding this Rails feature? Thanks a lot.
protect_form_forgery just adds a before action to the controller which checks if the authenticity_token is valid.
The :with parameter specifies how the controller should behave if the token is invalid.
with: :exception: raises an exception in the controller which can by catched.
with: :null_session: resets the session itself. This means the complete session will be deleted. In other words the session cookie will be reset. For example an user_id stored in the session won't be available anymore (puts session[:user_id] # => nil). So you always have to provide a token or any other authentication, which is perfectly fine for an API.
You can also remove protect_from_forgery if you don't use session.

Get around CSFR token for iOS app

I am developing an iOS app for a RoR api (my co-worker made it). I am trying to develop the login portion, but while testing the api in POSTMan, I noticed it requires a CSRF token. Is there a way to get around doing an api call to get the CSRF?
Side note: I am using AFNetworking 2.0
There are a couple things you can do:
You can launch a GET request before you do the post, and retrieve the sessions CSRF token. Then submit the POST form with an authenticity_token parameter as the proper CSRF token. You can embed the original token anywhere in the view with the rails helper form_authenticity_token, or just get it from the sign up form's hidden tag. (This is my favorite option)
You can make a secondary loggin-in action on your site that is actually a GET request in and of itself. It's not too dangerous to bypass the CRSF token here because anyone should have access to log in. This has the advantage of keeping CRSF for any other action you may need, but it wouldn't work for actions that need more security.
You can make your iOS page consist of a UIWebView. I'm not sure if this will suit your needs, but it would have the proper CSRF token and you can remove the UIWebView after submitting. It's kind of like option 1, but bulkier.
Good luck!
Easiest fix is to change the server side to not authenticate the CSRF token. Here's an example of using a different controller for your API.
class Api::BaseController < ApplicationController
skip_before_filter :verify_authenticity_token
end
In general, your API is either going to require authentication for API calls (in which case you should have your own authentication, or OAuth, or any number of authentication mechanisms) or isn't (in which case it's a publicly accessible API and CSRF doesn't matter). There a few other threads here and here that discuss it.
From another answer on SO (go upvote it!):
CSRF attacks rely on cookies being implicitly sent with all requests to a particular domain. If your API endpoints do not allow cookie-based authentication, you should be good.

Chrome extension: Send AJAX form to Rails app

I'm trying to make a Chrome extension for my Rails App that sends POST data with an ajax form. But, I get the response from the server:
ActionController::InvalidAuthenticityToken in AppController#getpostdata.
So I think I need to get an authenticity token and include that in my form.
Or, should I turn it off? And how?
Thanks
You can retrieve the token using the form_authenticity_token helper in a Rails view, during a GET request..
Alternately you can disable the token, or alternately use the :null_session option as this is considered the best for APIs. Consult the documentation for further info.
You can also skip the particular api method call in the controller as given below:
skip_before_filter :verify_authenticity_token, :only =>[:method_name]

Resources