Do any modern browsers ever issue an HTTP HEAD request? - http

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)

Related

*Concrete* risks of using HTTP GET for requests that have side-effects? (I know the theory.)

I know that, in principle, HTTP GET requests shouldn't have any side-effects (i.e. idempotent).
But I'm experimenting and, so far, my test HTTP GET requests that change data on a test database work just fine: it doesn't look like the HTTP GET requests ever get re-requested.
Now my tests are not representative of the real world. In the real world, any middle-man (e.g. Cloudflare) could take in consideration the fact that the HTTP request is GET and re-request the HTTP request, for example upon flaky networking. But I wonder if this actually ever happens?
Note that the HTTP requests in question are all browser-side fetch() JSON requests using the Fetch API. (I think that's relevant because while Cloudflare does re-request HTML resources, I don't think Cloudflare would ever re-request a fetch() JSON request.)
My gut feeling says that, while in theory such HTTP GET requests are allowed to be re-requested, it doesn't happen in practice. Am I right or is there a situation showing that I'm wrong?
Context
I'm the author of Telefunc which is a JavaScript/TypeScript RPC implementation and I'd like to make all Telefunc's HTTP request be GET, even when the user makes database changes. I'd like to do this because this would enable Telefunc to support ETag caching for all requests and without the user having to configure anything.

Are JSON web services vulnerable to CSRF attacks?

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?

Is the HTTP 'HEAD' verb useful in web development?

I've read the w3.org spec on the 'HEAD' verb, and I guess I'm missing something. I can't see how it would be useful.
Is the HTTP 'HEAD' verb useful in web development?
If so, how?
From RFC2616:
This method (HEAD) can be used for obtaining
metainformation about the entity
implied by the request without
transferring the entity-body itself.
This method is often used for testing
hypertext links for validity,
accessibility, and recent
modification.
The reason why HEAD is preferred to GET is due to the absence of the message body in the response making it using in scenarios where you want to determine if the content has changed at all - a change in the last modified time or content length usually signifies this.
Also, a HEAD request will provide some information about the server setup (whether it is IIS/Apache etc.), unless the server was masked; of course, this is available in all responses, but HEAD is preferred especially when you don't know the size of the response. HEAD is also the easiest way to determine if a site is up or down; again the irrelevance of the message body makes HEAD the ideal candidate.
I'm not sure about this, but RSS/ATOM feed readers would use HEAD over GET to ascertain if the contents of the feed have changed.
The HTTP HEAD can also be used to pre-authenticate to web server, before you do HTTP PUT/POST of some large data. Without the first HEAD request, you would be sending the large data to web server twice (because the first request would return 401 unauthorized reponse with WWW-authenticate header).
It's mainly for browsers and proxies to determine whether they can use a cached copy of the web document without having to download the whole thing (which would rather defeat the purpose of a cache).

What's the packet-level difference between an XMLHttpRequest and a regular HTTP request?

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.

How does server know to return gzipped data?

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.

Resources