In light of the comments from Mike Campbell
, I was able to determine that CORS requests are not treated as ajax
(xhr
) by default
The problem lies in the headers which are passed on an Ajax request. Standard ajax passes the following header:
#actionpack/lib/action_dispatch/http/request.rb
def xhr?
@env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/
end
This is passed with a "naked" Ajax request, which allows the xhr?
method to return either true or false. The issue is in a CORS ajax call, this header is not passed. I don't know why, but it just sends an ORIGIN
header instead
The proposed fix from Github suggested to include this:
uri.host != @env['HTTP_HOST'] || uri.scheme != @env['rack.url_scheme'] || uri.port != @env['HTTP_PORT'].to_i
This would basically return a boolean response based on whether the request was from the same domain as the script. Although this was prevented for being unsafe, it lead me to two fixes:
- Append a new
cors?
method to the Rails core- Send the
http_x_requested_with
header through a CORS request
Considering we are just trying to access a subdomain with the request, we felt that editing the Rails core was slightly overkill, although right. Instead, we found that using the inbuilt headers
argument in jquery would help:
$.ajaxSetup({ headers: {"X-Requested-With": "XMLHttpRequest"}});
Whilst this works, I am eager to hear about any security issues it may present. And plus, whether we can access json
and other formats with it