We can change the Origin header in AJAX request or using the Chrome's plugin 'Modify Headers'.
Therefore we can access data from the another host.
So is it reliable approach to handle CORS ?
HTTP_ORIGIN is neither sent by all browsers nor is it secure.
Nothing sent by the browser can ever be considered safe.
HTTP is a plain-text protocol. The ENTIRE request header/body structure can be faked to say anything you want.
Related
I understand what a HEAD request is, and what it could be used for. Will any standard, modern browser ever send a HEAD request? If so, in what context?
A browser will send a HEAD request if that is explicitly requested in an XMLHttpRequest, but I'm fairly certain that the browser will never send a HEAD request of its own accord. My evidence is that the Tornado web server defaults to returning an error for HEAD requests and I've never heard of anyone running into problems related to this (or even being aware of it).
HEAD is mostly obsolete IMHO: on a dynamic web site it is unlikely to be significantly more efficient than a GET, and it can usually be replaced by one of the following:
Conditional GET with If-Modified-Since or If-None-Match (used for caching)
Partial GET with Range header (used for e.g. streaming video)
OPTIONS (used for CORS preflight requests)
I am building a web service that exclusively uses JSON for its request and response content (i.e., no form encoded payloads).
Is a web service vulnerable to CSRF attack if the following are true?
Any POST request without a top-level JSON object, e.g., {"foo":"bar"}, will be rejected with a 400. For example, a POST request with the content 42 would be thus rejected.
Any POST request with a content-type other than application/json will be rejected with a 400. For example, a POST request with content-type application/x-www-form-urlencoded would be thus rejected.
All GET requests will be Safe, and thus not modify any server-side data.
Clients are authenticated via a session cookie, which the web service gives them after they provide a correct username/password pair via a POST with JSON data, e.g. {"username":"user#example.com", "password":"my password"}.
Ancillary question: Are PUT and DELETE requests ever vulnerable to CSRF? I ask because it seems that most (all?) browsers disallow these methods in HTML forms.
EDIT: Added item #4.
EDIT: Lots of good comments and answers so far, but no one has offered a specific CSRF attack to which this web service is vulnerable.
Forging arbitrary CSRF requests with arbitrary media types is effectively only possible with XHR, because a form’s method is limited to GET and POST and a form’s POST message body is also limited to the three formats application/x-www-form-urlencoded, multipart/form-data, and text/plain. However, with the form data encoding text/plain it is still possible to forge requests containing valid JSON data.
So the only threat comes from XHR-based CSRF attacks. And those will only be successful if they are from the same origin, so basically from your own site somehow (e. g. XSS). Be careful not to mistake disabling CORS (i.e. not setting Access-Control-Allow-Origin: *) as a protection. CORS simply prevents clients from reading the response. The whole request is still sent and processed by the server.
Yes, it is possible. You can setup an attacker server which will send back a 307 redirect to the target server to the victim machine. You need to use flash to send the POST instead of using Form.
Reference: https://bugzilla.mozilla.org/show_bug.cgi?id=1436241
It also works on Chrome.
It is possible to do CSRF on JSON based Restful services using Ajax. I tested this on an application (using both Chrome and Firefox).
You have to change the contentType to text/plain and the dataType to JSON in order to avaoid a preflight request. Then you can send the request, but in order to send sessiondata, you need to set the withCredentials flag in your ajax request.
I discuss this in more detail here (references are included):
http://wsecblog.blogspot.be/2016/03/csrf-with-json-post-via-ajax.html
I have some doubts concerning point 3. Although it can be considered safe as it does not alter the data on the server side, the data can still be read, and the risk is that they can be stolen.
http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/
Is a web service vulnerable to CSRF attack if the following are true?
Yes. It's still HTTP.
Are PUT and DELETE requests ever vulnerable to CSRF?
Yes
it seems that most (all?) browsers disallow these methods in HTML forms
Do you think that a browser is the only way to make an HTTP request?
I have a specific question about the http-protocol?
I know that the http protocol handles request/response, but does it also handle the cookies?
Cookies are set using HTTP Response headers and sent using HTTP Request headers.
See also: the original and updated cookie specifications
Cookies are transported in HTTP requests and responses, but are not part of HTTP.
See RFC 6265.
Yes. It handles cookies. All cookies are sent over HTTP requests of the same cookie domain parameter (including wildcard domain).
YES this same protocol is responsible for handling the cookies.. i mean the browser that says that it can handle HTTP protocol shud also handle cookies.
see the link http://en.wikipedia.org/wiki/HTTP_cookie#Implementation
and there are a lot more things in HTTP other than Req/Res and cookies.. in fact the cookie thing is a part of the req/res.
visit this link
http://www.w3.org/Protocols/rfc2616/rfc2616.html
I'm wondering: if I were a a router, packet inspector, firewall, or other packet-sniffing device (which I'm glad I'm not) would I be able to tell the difference between a traditional HTTP request and an XMLHttpRequest? Less theoretically, is it possible that some ISP or (let's say) cell phone data provider could restrict XMLHttpRequest traffic without interrupting HTTP service?
Thanks.
There's nothing at the packet level to distinguish them because and XMLHttpRequest is an HTTP request. The XML bit refers to the fact that if the response is of an xml Content-Type then the responseXML method will return a DOM Object.
To the best of my knowledge, there is no fundamental difference - so from the point of view of a router etc. you can't tell in general.
But I do believe that most popular Javascript toolkits will add an HTTP header to their XMLHttpRequests to identify them as such. I forget the name, though...
EDIT: Here's an example (top Google hit for "jquery xmlhttprequest header", no quotes) that shows that jQuery apparently sets X-Requested-With to "XMLHttpRequest".
at packet, network, session levels: no.
at application level, that is with an HTTP-specific device like a filtering proxy, maybe.
i'd check the HTTP request headers. they might (just might) have some differences. but i'm sure any difference there would be very browser-specific, and quite probably the right JavaScript code could insert the appropriate headers to make it totally indistinguishable.
in short: check the HTTP headers; but don't expect it to be general, much less useful.
In the header exchange below I see that the server is returning the page Gzipped but I don't see where my browser ever indicated that it could accept GZip. How did the server know?
The content you have reproduced here is not what was sent by your browser; the "general" part is a mix of some of the request data and some of the response data. If you want to see the actual request an response, use something like wireshark.
Coincidentally, it is worth noting that some so-called security products will interfere with your browsers request - a common "enhancement" is to remove or mangle the header asking for compression. Your webserver will honour such requests in the absence of specific configuration to force compression. Google delivers a compressed JavaScript to the client when it sees such behaviour - if it runs on the client then Google start sending compressed content. There are Apache config snippets on the web which can detect and override some such tampering.
But there's no evidence here to suggest that is the case with your setup. You're just not seeing the request headers.