Please read my blog's comment policy here.
Over the five years I’ve worked on Internet Explorer, I’ve probably seen more questions from the community about HTTP cookies than on any other topic. Cookies are an integral component of most websites in use today, and hence problems or unexpected behaviors with cookies tend to get a lot of attention.
In this post, I’ll try to summarize the most common questions and answers I’ve seen related to Internet Explorer’s implementation of cookies. I may add to this FAQ over time.
Q1: IE’s cookie code doesn’t seem to support <something> as defined in RFC2109 or RFC2965.
A: Correct. Internet Explorer (including IE8) does not attempt to support any RFC for cookies.
WinINET (the network stack below IE) has cookie implementation based on the pre-RFC Netscape draft spec for cookies. This means that directives like max-age, versioned cookies, etc, are not supported in any version of Internet Explorer.
Q2: If I don’t specify a leading dot when setting the DOMAIN attribute, IE doesn’t care?
A: Correct. All current version browsers (Chrome, FF, Opera, etc) seem to treat a leading dot as implicit. Here’s a test case.
Q3: If I don’t specify a DOMAIN attribute when a cookie, IE sends it to all nested subdomains anyway?
A: Yes, a cookie set on example.com will be sent to sub2.sub1.example.com.
Internet Explorer differs from other browsers in this regard. Here’s a test case.
Q4: How many cookies will Internet Explorer maintain for each site?
A: As of August 2007, the per-host limit was increased from 20 to 50. The August update applied to IE5, 6, and 7. IE8 natively can support 50 cookies per host, and Firefox uses the same limit.
It’s worth mentioning that increased cookie limit actually broke the website of a major financial institution. The site depended on cookies beyond the 20 cookie limit getting dropped, and stopped working properly when the limit was increased. This is just one example of how tightly-coupled today’s web is to IE’s cookie implementation. That, in turn, is one reason why the IE team must exercise great care when making any change to IE’s cookie implementation.
The document.cookie property is limited to 10KB.
WinINET will not respect a Set-Cookie response header value longer than 5118 bytes. WinINET allows 50 cookies, each of which is ~5kb long. Hence a request could carry 250kb of cookies. (eek!)
Q5: IE won’t set a cookie when the hostname/domain contains an underscore?
A: Correct. Technically, an underscore (like this _ ) is not a DNS character, and while Windows will let you use an underscore when naming your machine, it warns you that doing so may cause problems. One such problem is that WinINET blocks attempts to set cookies on such domains. See http://support.microsoft.com/kb/316112/en-us
Q6: IE won’t set a cookie for certain domains, like those of the format http://xx.yy?
A: Correct. The idea is that you may not set a cookie on a "top-level" domain shared by unrelated organizations. Historically, ccTLDs of the format xx.yy were effective TLDs, so cookies may not be set on them. While this heuristic was never perfect, it's been unchanged for over 15 years and hence is not likely to change any time soon. The intricacy of this issue merits a long blog post all its own-- see this post.
Q7: My site is not receiving cookies when it is running in an IFRAME and the parent page is from a different domain. Why?
A: Internet Explorer has restrictions on “3rd party” cookies. 3rd party cookies are cookies which are set or sent for resources from a different domain than the top-level browsing context. You can easily confirm P3P/Cookie restrictions as the root cause of such issues by temporarily changing IE’s Tools / Options / Privacy setting to “Accept All Cookies”.
In order to allow such cookies to be sent reliably, you should send a P3P header when setting the cookie.
You can use Fiddler’s “Privacy Inspector” to view and analyze any P3P Policy. To learn more about P3P and IE, see my quick P3P guide.
Q7b: My page doesn't receive or set cookies when it is running in an IFRAME with the SECURITY=RESTRICTED attribute. Why?
A: The SECURITY=RESTRICTED attribute on IFRAMEs indicates that the browser should treat the content as if it came from the Restricted Sites zone. Content in this zone cannot set or read cookies. Cookies will not be sent to the server, and cookies will not be set if received from the server. To resolve this problem, you will need to communicate any necessary state information to the server via another mechanism (e.g. a token in the URL).
Q8: Are there any limits to the HTML DOM document.cookie property?
A: In IE5, 6, and 7, if the cookie string is longer than 4096 bytes, the document.cookie property will return an empty string. For IE8, this limit was increased to 10Kb.
Also, due to an obscure bug in the underlying WinINET InternetGetCookie implementation, IE’s document.cookie will not return a cookie if it was set with a path attribute containing a filename.
For instance, if a page sets a cookie on itself like so:
…the cookie will be sent with HTTP requests but will not appear in the document.cookie collection.
Q9: Cross-Site Scripting attacks (XSS) can steal cookies. What can I do?
A: Determine if you need to expose your cookies to scripts running on your site. If your cookies are only used by your server, and your scripts don’t require access to your cookies, use the HttpOnly attribute to help protect your site against cookie theft via cross-site scripting attacks.
Simply add the HttpOnly attribute to each Set-Cookie header, and Internet Explorer will ensure that your cookie is not available to any script running in your pages. Cookies with the HttpOnly attribute are still sent in each HTTP request, but will not appear in the script-accessible document.cookies property. This means that if a hacker finds a cross-site scripting hole in your site, he cannot easily use the hole to steal logged-on visitors’ cookies.
The HttpOnly attribute is supported in all modern browsers (IE6+, FF3+, Safari 4, Chrome, Opera 9.5+).
Q10: How can applications or native code add-ons set cookies?
A: Applications should set cookies using the InternetSetCookieEx function, passing the appropriate flags to indicate if a cookie is being set from a 3rd party context, and any P3P directives available. The non-EX version of this function will unconditionally set a cookie (even if “Block all cookies” is set in IE’s settings) although such cookies will not be subsequently sent to servers while the “Block all cookies” setting is active.
Note: On Windows Vista and above, Internet Explorer runs Internet content in Protected Mode, a sandbox with an isolated cookie store. In order to set a cookie in the Protected Mode sandbox from an external application running at Medium integrity (aka outside of Internet Explorer), you must use the IESetProtectedModeCookie function. This API was added in IE8, and unfortunately, there is no straightforward alternative for IE7. This API has a number of limits, in particular, it cannot be called by processes running at High Integrity (Admin), and it does not have an option to provide the P3P policy string when setting the cookie.
IE10+ on Windows 8+ introduced Enhanced Protected Mode which uses AppContainers (rather than Integrity Levels) for isolation. EPM does not offer an API for interacting with cookies; IESetProtectedModeCookie will not set the cookie inside an AppContainer.
Q11: How can applications or native code add-ons retrieve cookies?
A: Use the InternetGetCookieEx function.
Note, by default, the cookies returned from this function will not include any HTTPOnly cookies. To retrieve HTTPOnly cookies, you must pass the INTERNET_COOKIE_HTTPONLY flag, available in IE8+. If you decide to pass this flag, you must ensure that your code will not expose the returned value to any script-controllable context. (Note: It appears that support for the INTERNET_COOKIE_HTTPONLY flag was added to IE7 in a cumulative update (KB960818)).
Note: On Windows Vista and above, Internet Explorer runs Internet content in Protected Mode, a sandbox with an isolated cookie store. In order to get a cookie from the Protected Mode sandbox from an external application running at Medium integrity (aka outside of Internet Explorer), you must use the IEGetProtectedModeCookie function. This API was added in IE8, and unfortunately, there is no straightforward alternative for IE7. This API has a number of limits, in particular, it cannot be called by processes running at High Integrity (Admin).
IE10+ on Windows 8+ introduced Enhanced Protected Mode which uses AppContainers (rather than Integrity Levels) for isolation. EPM does not offer an API for interacting with cookies; IEGetProtectedModeCookie will not get the cookie inside an AppContainer.
Q12: How can I log into my web application multiple times? How are cookies shared between IE windows?
A: Good question, and the answer has changed a bit in IE8. I wrote up a full post on the subject over on the IEBlog.
Q13: How can I control (block, downgrade or allow) cookies?
A: See Internet Explorer Cookie Controls.
That’s it for now; thanks for reading!
InternetSetCookie function, unconditionally sets a cookie (even if “Block all cookies” is set in IE’s settings). I want to allow such cookie to be subsequently sent to the server( while the “Block all cookies” setting is active).
Please suggest a way to achieve this.
@Ravi: You'll have to provide more details. IE will not send cookies to Internet-zone servers when "Block all cookies" is set for the privacy settings.
i wanna delete a cookie by setting a past expire date using InternetSetCookie.
[broken code removed]
@bob: Your code sample is corrupted by the blog software. Send me email directly (ericlaw at microsoft)
Regarding Q7, setting cookies from difference domain inside iframe.
P3P is often a solution - or Thu I am not really sure if it is always enough.
I wonder regarding Q7:
1. Does it make any difference if its a session cookie, or a permanent cookie ?
2. Does it make any difference if the different domain is just a subdoamin, or really a different domain ?
3. (this is kind of tricky) - does it make any difference for the IE privacy check, what ip adress the domain is hosted on, or does
IE only react on the domain name itself ?
Best regards and thanks if someone has something to add - I will try to check out on these three questions on my own, and return here later on.
@Anders: P3P is *the* setting that controls.
1> P3P changes behavior depending on whether it's a session cookie or a permanent cookie. Sometimes permanent cookies are "downgraded" to session cookies.
2> "subdomains" may be treated as "different" domains when it comes to P3P; I haven't looked at this recently and need to recheck.
3> No, IE doesn't care about the IP address for this, or any other privacy/security check based on hostname.
Re 2> It seems to me, in general, that cookies in iframes is much more accepted when the iframe is a subdomain hostname.
I am using WinInet APIS for http req/response in my c++ application. and I want to send cookie (regrdless of IE’s settings).
I tried INTERNET_OPTION_SUPPRESS_BEHAVIOR value = INTERNET_SUPPRESS_COOKIE_POLICY but that didn't work. I want to know whether it is possible to send the cookie (progrmatically nat using IE) even if user has set IE to block all the cookies. If yes then please suggest how?
Any help/pointer would be very helpful
in webbrowser control, when a webpage change the cookie by JS(document.cookie="..."). how can i get the notify?
because i would like to get the cookie value.
@Mike: There's no reliable/non-hacky way to do that.
The hacky ways would be to do something like inject a script function into every page that wraps the document.cookie object and notifies your application that the method is being called. Or you could implement IInternetSecurityManager and watch for tests of the cookie-related URLActions, but you would only be able to use this to know when something might have changed; you'd need to call InternetGetCookie to get the cookie and manually look for any changes.
What can cause IE7, for example, to create a numerically incremented version of a cookie file? For example, if this cookie exists:
then what might cause this file to get created:
@Allan: The name of the text file on disk is an internal implementation detail upon which a dependency should not be taken.
Generally speaking, WinINET's file creation logic will append increasing numbers [n] after filenames in order to ensure uniqueness. The use of a  suggests that a file named  existed at some point in time when a new file needed to be created.
A: Yes, a cookie set on example.com will be sent to sub2.sub1.example.com. Internet Explorer differs from other browsers in this regard.
I am experiencing a problem with this:
As you pointed out, when executing code at a domain named x.y.z, Internet Explorer sends the cookies for x.y.z and the cookies for y.z. PHP then puts both sets of cookies into $_ENV["HTTP_COOKIE"]. Now what shall I do with multiple cookies sharing the same name? Can I reliably assume that the first one is for x.y.z? Does $_COOKIE["cookiename"] always contain the first cookie named cookiename? Can I rely on that?
... Warren Gaebel, B.A., B.C.S.