authentication token verification for AJAX/xhr requests in rails - ruby-on-rails

Seems that Rails has by default stopped checking authentication_token for ajax requests. per code request.xhr? is not checked anymore. It was not ignored in rails 2.3.2 but since 2.3.8 is ignored. Wanted to know what is the reason for this change and what uis the way to turn it on.

You need now check the format of the request to know what your want really served. It's really better than to know if you request is or not in xhr. This trick was bad because can be not support by all Javascript script.

Related

How to pass CSRF token for Rails post request in paw-app

I am attempting to use the Paw app to test out a REST API build in Rails 4.2.4. I have a create method which expects JSON as input. The request appears to pass the correct information from Paws as structure, but the Rails API is failing with the following error:
422 Unprocessable Entity
Can't verify CSRF token authenticity
When writing the JavaScript front end, the request must have a header appended to the request, of the form:
webix.ajax().headers({'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}).post("geo_wells.json", parms), function(text){webix.message("posted");});
That all works fine for getting the CSRF satisfied consistently, although it's the parms I am trying to use Paws to help sort out. But I can't get that meta token in Paws. No idea how to actually add that to the header of the request. Tried creating a cookie and all response cookies, but that didn't do it either.
Any ideas? I'd like to purchase the tool, but if it can't do this, it's not of that much use to me. I would prefer not to up and disable the CSRF as is so often suggested. I'm hoping for a robust answer that would still extend to testing of the fully CSRF enabled API.
This Paw.app article had the answer.
First, install the RegExMatch extension.
See: https://paw.cloud/extensions/RegExMatch
With the Ruby on Rails getting started set up, the regex required to get the csrf token was below:

Why should spring postOnly be false for Logout to work?

what does postOnly mean in below property
grails.plugin.springsecurity.logout.postOnly=false?
Why should it be false for Logout to work? Tried making the logout feature work by making it true. But it did not work. What is the reason behind making it false?
For starters, please read the plugin documentation - the 2.x docs are here and the 3.x docs are here.
The plugin defaults to requiring a POST request to logout, but using the config setting you reference you can make your application more convenient to use but less secure by allowing GET or POST requests.
GET requests (e.g. regular links) are supposed to be for actions that read data. A strict REST API requires that GET requests be read-only and also idempotent, but obviously in a regular web app this is too strict. But in general it's best to use links and GET requests to request information, and POST/PUT/DELETE/etc. requests to make changes.
If you include a logout link that uses GET to make the request, it's possible for someone using XSS or similar attacks to trick your browser into logging you out. This isn't a severe vulnerability and requiring POST doesn't make it significantly harder for an attacker but it does raise the bar.
With the default configuration all you need to do is replace a logout link with a simple form that POSTs to that same url (and you can optionally use CSS to style the submit button like a link if you want). If you're comfortable with allowing users to logout with a GET request, change the setting to false and any request to that url will work.
Once you make it true as below
grails.plugin.springsecurity.logout.postOnly=true
the request method type should be POST only i.e. you can't use GET method.
So, change the logout call to POST type in this case.
You may also look at How to customize Grails Spring Security Core 2 login / logout controller and views?
By default Spring Security requires logout to use a POST request to provide CSRF protection. For more on CSRF see Wikipedia.
what does postOnly mean in below property
I means you grails will only logout a user if you send a POST request to the logout url.
Why should it be false for Logout to work?
It's mainly for CSRF protection.
It is considered best practice to use an HTTP POST on any action that
changes state (i.e. log out) to protect against CSRF attacks. If you
really want to use an HTTP GET, you can use logoutRequestMatcher(new
AntPathRequestMatcher(logoutUrl, "GET"));
Additionally, modern browsers like chrome will preload links in a page before the user tries to access them to make them fast. This means if you make your logout link accept GET requests, chrome might log you out even if you don't want to.

Rails cross-domain requests security concerns

I am developing a Rails app which relies on a lot of jQuery AJAX requests to the server, in the form of JSONs. The app has no authentication (it is open to the public). The data in these requests is not sensitive in small chunks, but I want to avoid external agents from having access to the data, or automating requests (because of the server load and because of the data itself).
I would ideally like to include some kind of authentication whereby only requests can only be made from javascript in the same domain (i.e. clients on my website), but I don't how or if this can be done. I am also thinking about encrypting the query strings and/or the responses.
Thank you.
What do you mean only your app should request these JSONs? A client will eventually have to trigger an event, otherwise no request will be sent to the server.
Look at the source code of any of your app's pages. You will notice an authenticity token, generated by the protect_from_forgery method in your application controller - from the api:
Turn on request forgery protection. Bear in mind that only non-GET, HTML/JavaScript requests are checked.
By default, this is enabled and included in your application controller.
If you really need to check whether a request comes from your own IP, have a look at this great question.
I want to avoid external agents from having access to the data... because of the server load and because of the data itself.
If you're really concerned about security, this other question details how to implement an API key: What's the point of a javascript API key when it can be seen to anyone viewing the js code
You shouldn't solve problems you don't have yet, server load shouldn't be a concern until it actually is a problem. Why don't you monitor server traffic and implement this feature if you notice too much load from other agents?
I ended up passing token=$('meta[name=csrf-token]').attr("content")in the request URL and comparing with session[:_csrf_token] in the controller.
def check_api
redirect_to root_url, :alert => 'effoff' unless request.host =~ /yourdomain.com/
end
that should work to check your domain. Not sure you need the js part, but it's something.

Rails - Session not saving

I have a session that is set but it does not appear to carry over to other pages. I'm on Rails 2.3.5 and Ruby 1.8.7. Has anyone else experienced this issue?
I've had this issue in Rails 3.1 when CSRF verification fails. This can happen if you use a tag manually rather than generate it via one of the built-in methods provided by Rails.
Search your log file for "csrf" (case insensitive search). If you see a log entry showing a csrf failure, it's likely Rails is resetting your session.
You may be losing your session between requests which can happen if it's not established properly in the first place. If you examine your cookies you may see the session identifier changing, being re-assigned, because of a validation failure.
It's also possible that it's being assigned to a domain that the browser subsequently rejects. This happens if an application is configured to use a specific domain, and is then re-hosted under a different one, even localhost.
You might have not used csrf meta tag in your layout. Try removing ' protect from forgery ' in application_controller.rb in controllers folder. Then try running the app again, if it works then you didn't add tags to your layout.

Rails POST doesnt extract any path, query or request parameters

I want to grant users access to my API (hosted on heroku.com) from their sites.
But a strange problem occurs, when i want them to allow to post to the api:
Data sent from an correct form with the correct action-url (e.g. "http://myapp.com/projects/123/tasks/321/todos") - the params get serialized and send via jQuery - i encounter an "ActionController::MethodNotAllowed" with the additional info: "Only get and post requests are allowed", that re-routes to ApplicationController#index with :method => :options.
Rails doesnt extract the params for project_id (123) and task_id (321) from the url, neither are any further request_parameters, path_parameters or query_parameters available.
This behaviour occurs, when I POST from external sites, but doesn't occur, when posting from an html-page on my local machine. My first thought was about wrong encoding, but how to fix that problem.
Edit:
I am using authlogic (not devise :-D) and for the :create action the protect_from_forgery is already skipped.
Any suggestions appreciated
i guess that happens because rails tries to protect your form CSRF attacks.
you can comment out the protect_from_forgery line in your ApplicationController to test it.
but im not sure if thats the right way of dealing with this issue in the production environment.
Okay. I'll try and answer the right question this time (see other comment).
So I've thought about this, and I'm wondering, is this a case of the jQuery call attempting a PUT request? When you use the local form Rails will POST the data, but add the extra _method field to emulate a PUT.
Don't know if you are using jquery-rails, but this takes care of setting the _method parameter, and the PUT/POST verb translation for you in your AJAX calls.
The problem occured due to the cross domain policy - the request was made from another domain - and because I was using a recent browser that supports CORS, it was sending an OPTIONS-request first to get known from the server, which actions are allowed for this domain.

Resources