Sunday, November 27, 2016

Cookie limits - browser side

If you search the net for 'cookie limits', you'll find this site http://browsercookielimits.squawky.net/ (or variations of it). I was baffled that max total cookies size is a 'guess' within a fairly large interval. So I set to write my own version and hope to get more accurate numbers.

Here  is the result: http://alinconstantin.com/download/browsercookies/cookies.html

It turned out the limits guessed were accurate already (no variation interval was necessary). But it was interesting to learn more about cookies and javascript. Here are a few notes.
  • JavaScript support for cookies sucks, it's a weird mechanism. Setting a cookie is done by setting a property, document.cookie, but reading back that property returns all cookies set (just names and values, even though cookies set could have other properties like path or expiration dates)
  • If you set cookies from JavaScript, don't forget to remember the names of cookies set in a separate list! If you set cookies with values that go over the browser limit per domain, browsers like IE/Edge will clear up the property document.cookie, and you'd have no way to enumerate existing cookies (to know what to delete before being able to set new cookies). Fwiw, this behavior is browser dependent, Chrome/FireFox will drop oldest cookies instead...
  • IE support for JavaScript sucks. In IE11, string.startsWith(), string.repeat() are not implemented, delegates var f1 = () => {dosomething();} are not understood, etc. Edge is better in this regard.
  • Chrome is silly, not allowing using cookies when scripts are run from file:// locations.
  • IE & Edge have very low limits for total cookies size. You probably don't want to send 10k cookies with every http request, but I've seen websites hitting these limits... 15k would have been more reasonable (and closer to the 16k default limit of header sizes in server side). On the plus side, 5k per cookie is better than the ~4k of all other browsers (and I've seen websites hitting that limit in other browser, too)(
Anyway, here are the results for cookies limits for the major browsers as of writing this article:

Browser   Max bytes/cookie   Max cookies   Max total bytes for cookies
IE11 & Edge 5117 50 2*5117 = 10234
Chrome 54 4096 180 180*4096 = 737280
Firefox r50 4097 150 150*4097 = 614550
Opera 41 4096 180 180*4096 = 737280

Thursday, November 24, 2016

Cookie limits - the server side story

If you search the net for 'cookie limits', you'll find this site http://browsercookielimits.squawky.net/ (or variations of it) that list browser-side limits for cookies for a couple of browsers.
RFC2965 will tell you a browser should support at least 20 cookies of size 4096 bytes per cookie, but browsers usually support higher limits. E.g. Chrome supports 180 cookies of size 4096 bytes, per domain, with no limits for the total size of all cookies. That makes 720Kb of data that is allowed by Chrome in each request.

In reality, even if you insist of sending that crazy big amount of data with every http request, you'll discover it's impossible to use that many cookies. Depending on the server accessed, you may be able to use only max 3 cookies of size 4096 bytes! Why? Because there is another side of the story - the servers you are accessing will also limit your use of cookies sizes.

Those limits depends from http server to server, and the server response if you make larger requests varies, too. Here are some examples:
  • www.microsoft.com - throws SocketException / ConnectionForcefullyClosedByRemoteServer after ~16k max cookies
  • portal.office.com - Starts returning "400 Bad Request – Request Too Long. HTTP Error 400. The size of the request headers is too long" after max ~15k cookies
    www.google.com - Starts returning 413 Request Entity Too Large after ~15k cookies
  • www.amazon.com - Starts returning 400 Bad Request after ~7.5k
  • www.yahoo.com - Accepts requests up to ~65k, after that returns 400 Bad Request 
  • www.facebook.com - Accepts about ~80k after that starts returning 400, 502 or  throws WebException/MessageLengthLimitExceeded (seems dependent on the number of cookies, too)
Per https://support.microsoft.com/en-us/kb/820129, IIS Server defines two configuration settings, MaxFieldLength and MaxRequestBytes that limits the size of the http request headers that are accepted. This includes things like the RequestUrl being accessed, the User-Agent string, AAD authentication tokens, etc, thus limiting the size of Cookies stored in headers, too. For IIS, that limit is 16Kb by default, and can be configured. Probably Apache has similar limits, and website owners may have adjusted the limits.  

If you're writing a web application and use cookies pushing the limits, it's important to know what your server will tolerate on incoming requests.

I wrote an app one can use to test and get an idea of the server limits. You can download it from
http://alinconstantin.com/Download/ServerCookieLimits.zip and invoke it with the http:// Uri of the server to test for parameter. The app makes requests to the server with cookies of various decreasing sizes, trying to narrow down the accepted max cookies size. The output looks like in the picture below.