Security for cross-origin resource sharing - ruby-on-rails

I have 2 ruby on rails app sitting on 2 different domains (say www.exampleA.com and www.exampleB.com. I want to share resources between the 2 apps and I'm using CORS:
exampleA.com sends http POST request to exampleB.com.
At exampleB.com I'm checking request.env['HTTP_ORIGIN'] to make sure that the request comes from exampleA.com. If true I respond by setting the response headers to allow the http post request.
My question is can I use request.env['HTTP_ORIGIN'] as the only check to verify the identity of requester?
Is it possible for someone from www.exampleC.com to fake their HTTP_ORIGIN to look like www.exampleA.com and post malicious data? If so what's the best way to verify requester identity?

Origin is one of several header fields that cannot be set for a XHR request by page authors. So you’re safe to trust the Origin information of XHR requests.
But it is still possible for an attacker to send forged requests with malicious data directly. So you’re still required to validate incoming requests.

Sorry, but it is trivially easy to fake most client-provided data, origin included, and hence it should not be used for any type of security.

Related

Is it possible in .Net MVC to return the JWT token for user-agent to include in subsequent requests automatically?

As captioned, is it possible to achieve this without using cookie or session,and without involving any JavaScript as well?
No, this is not possible without involving some persistence on the client that is going to make the subsequent requests. There's no such notion in the HTTP protocol (other than a cookie) that would indicate to the client to include some header on subsequent requests automatically. So basically if you don't like cookies you might find another place to store the access token on the client - the local storage in the browser seems like a good place and include it in subsequent requests that a javascript client would make. Of course if your clients are not javascript then they will have to find an appropriate place to store the access token.

Deny access to a rails route if request does not originate from app

I have a route in my application that returns results from an LDAP query. I'm using a privileged account for this as it needs to return information that a regular account can't access.
Is there a way to deny users access to this route if they're not using it via one of the application's views? What I'm trying to prevent is a someone reverse engineering it and building their own app to gain access to the PII.
There is no reliable way to say this request originated from this view vs. this request originated from (e.g.) the command line.
An HTTP URL request doesn't have a verifiable source of origination. There is a "referrer" HTTP header which is intended for saying where the previous request originated, but it is not for security and completely spoofable, and not even always included in the request.
Somehow you'll need to authenticate the request. Don't invent your own way. Use devise or some other tested tool to build an authentication strategy, and figure out how to modify your application to work with existing conventions of HTTP request authentication (secure token, cookie based auth, etc.)

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.

No browser is sending Authorization info in header

I'm looking at this and this and it would appear 'easy' to send the credentials in the URL. For example:
http://gooduser:secretpassword#www.example.com/webcallback?foo=bar
This is all well and good but it doesnt work. I've turned fiddler on and for Chrome the Authorization header isnt sent. It appears to exhibit the same behaviour for other browsers (i've got a breakpoint on the server and no Authorize header turns up for Firefox,Safari or IE either)
How to make it better?
Stumbled across this while researching various basic auth implementations.
Browsers generally only send basic auth if they receive a 401 challenge response from the server (more on basic auth protocol). If the endpoint in question accepts both authenticated and non-authenticated users, then a browser-based request will likely never be prompted for the auth parameters.
The easiest way to test this type of setup is to send a curl request (which sends the authentication parameters regardless) to your server endpoint and validate receipt of the authorization header:
curl 'http://gooduser:secretpassword#www.example.com/webcallback?foo=bar'
OK so after much searching and experimenting the approach
http://gooduser:secretpassword#www.example.com/webcallback?foo=bar
does work.
However one needs to be careful to ensure that the secret password DOES NOT contain any special characters. Use a password containing only letters and numbers and a hypen(if you must) and it should work.

CSRF Protection with HTTP GET requests in Rails

I understand that Rails by default doesn't have CSRF protection for HTTP GET requests, because, it claims they are idempotent. However, there is sensitive information that is returned to the user from these GET requests, and, I would't want a malicious site retrieving this information.
What is the best way to protect HTTP GET requests from CSRF in Rails?
To be able to read the response to a CSRF attack’s request, an attacker would need to get the victim to execute his JavaScript code. And in that case, the access would be restricted by some Same Origin Policy.
Assuming the attacking request is really cross origin, the Same Origin Policy for DOM forbids access via DOM (e. g. when embedded using iframe) and the Cross-Origin Resource Sharing (CORS) regulates cross-origin requests via XMLHttpRequest as follows:
If the request is a simple cross-origin request, i. e. simple method with only simple header fields, then that request will be sent (this is similar to HTML-based CSRF). But accessing a simple cross-origin request’s response depends on whether the response allows resource sharing.
Other cross-origin requests require a so called preflight before the actual request is sent. That request is sent to check whether the server allows requests from the origin the preflight is sent from. And only if the preflight succeeds and the response to the actual request allows resource sharing, the response can be accessed.
So to conclude: Unless your server supports CORS and explicitly allows sharing with any other origin (i. e. Access-Control-Allow-Origin: *), a CSRF response – if the request was allowed at all – won’t be readable by the attacking site.

Resources