I am right now developing web APIs with Ruby on Rails. When the Rails app receives POST request without any csrf token, the following error message shall happen. Because the app has no views.
WARNING: Can't verify CSRF token authenticity
So my question is how can I escape csrf token check safely in this case?
Thank you very much in advance.
You can do this by adding
skip_before_filter :verify_authenticity_token
to your controller. This way all incoming requests to the controller skips the :verify_authenticity_token filter.
For rails 4 it should be
skip_before_action :verify_authenticity_token, only: [:one_or_two_actions_here]
Note that you should avoid skipping verify_authenticity_token on all actions of your controller, instead use the option only to skip only where you have to. See the docs
Related
I have a question which i can't seem to figure out from all the googling. I am building a rails app basically an api app. When i give out post request it returns me with an error 'InvalidAuthenticityToken' so i used
skip_before_action :verify_authenticity_token
And after some googling i came to know that it is not recommended to skip this because our app will be vulnerable to CSRF attacks. I am also using doorkeeper gem for my authentication. My question is that even if i have the doorkeeper gem for authentication will my app be still vulnerable to attacks ?
I have also placed this code in my application controller and removed the above code
protect_from_forgery with: :null_session
Is this safe or can someone say how to properly implement this ?
It's good to have CSRF attack protection in your app. In api you can add this token to header and pass it between frontend and backend. I used this guide from pragmatic studio to set it up in my application:
https://pragmaticstudio.com/tutorials/rails-session-cookies-for-api-authentication
However, I have no idea how will it work with doorkeeper (haven't used it).
i have a cordova app connected to a laravel api.
I need to make a post from the mobile app to that laravel, but i need the csrf token.
I cannot do the {{csrf_field}} because the view i´m using in the mobile is not provided by laravel so no blade or laravel helpers.
I tried doing a previous ajax call only to get the token, but i don´t know if this is the best way to do it.
Thank you!
In your case I wouldn't recommend to you to get the CSRF token.
Instead I'd suggest you to construct a personal authorization code (per user) or removing the corresponding URLs from the CSRF check (maybe even the whole API).
The token is linked to the currently authenticated user. What you're trying to do won't work.
Try using the API middleware to login and store the token on the mobile app, and use that to identity yourself.
While as the other answers have said, this isn't a recommended solution for your problem, Laravel has a helper function to give you the CSRF token, aptly named csrf_token().
It's listed on the helpers page of Laravel's documentation: https://laravel.com/docs/5.4/helpers#method-csrf-token
My production server is not able to verify the csrf token.
I have added the tag for csrf in the application layout and sending it through headers.
In my request call I can see the token is included.
However my rails app is not able verify it.
Is there any way I can check what csrf token is my controller is expecting?
This is part of the code used in ActionController to check for authenticity
form_authenticity_token == params[request_forgery_protection_token]
form_authenticity_token will give you the token your controller is expecting.
Refer to the source code here
I have the following piece of code:
class Foo < ActiveRecord::Base
protect_from_forgery
end
My doubt is when the protect_from_forgery will be called? when an instance of Foo is created?
Thanks in advance
Someone with more knowledge than myself might know a better answer but here is how I understand it:
When the browser sends a post request, rails includes an additional authenticity token with the requests that corresponds to that users session. If I knew another users authenticity token, I could add an html element on the page that includes their token and submit requests posing as their user. This is called Cross Site Request Forgery. To protect your site from such attacks, rails includes a method called protect_from_forgery. This method should be placed at the top of your Application Controller so check each request for authenticity.
Further reading can be found on the Rails Guide to Security.
I'm building an API with Sinatra (using Angular for the client side and want others to have access to API) and have it also be an OAuth provider. I am wondering what the best route to take (work off existing gems or roll own solution off Warden or something).
Have used devise and doorkeeper for authentication and oauth before with Rails, wondering what best solution for Sinatra is.
Ideally I don't want the views or be able to extend/mod the actions of an existing solution, as I'm interacting with it purely as an API.
I just recently did the same thing using the following answer from S/O
What is a very simple authentication scheme for Sinatra/Rack
It implies a user model, but instead of using that, I just set a user and admin password in my config file. Then I had a login form that just took a password. When the user enters that password, I checked it against the one in settings and set the session['user'] to :admin or :user according to whichever it matched (or nil if none). Then on each of my routes, I called auth: :user or auth: :admin accordingly.
APIs normally accept your login request and send you an authentication token which you need to pass back in each call. This is very similar to cookie based sessions where your browser automatically passes back the cookie which is acquired on initial website visit.
From what I've seen in Sinatra's docs, you could make a session-based authentication system like this:
enable :session
disable :show_exceptions
use Rack::Session::Pool,
key: 'session_id'
post '/login' do
user = User.login_success(params)
halt 401 if user.nil?
session[:user] = user
200
end
get '/fun' do
user = session[:user]
halt 401 if user.nil?
halt 403 if !user.has_permission_for '/fun'
"fun was had"
end
Now all you need to do in your client is to pass back the cookie token returned in response to initial visit when requesting an API function. This can be done with any web client library that supports cookie stores (such as libcurl) or by inserting the session cookie into the request header manually. Rack::Minitest functionality also supports cookies, so you can test your API with minitest.
See Sinatra API Authentication.
Quick summary:
Sinatra has no built-in auth.
It's best to build auth yourself (see the link).
There are gems available, but you probably won't need them for something as simple as an API.