ASP.NET: Loss of Session / Cookies with Frames

Imagine if every Thursday your shoes exploded if you tied them the usual way. This happens to us all the time with computers, and nobody thinks of complaining. -- Jef Raskin

Recently we had a forum question on eggheadcafe.com where the user indicated they were losing Session because of the use of FRAMESET or an IFRAME.

If you implement a FRAMESET where frames point to other Web sites on the networks of your partners or inside your network, but you use different top-level domain names, you may notice in Internet Explorer 6 that any cookies you try to set in those frames are lost. This is most frequently experienced as a loss of session state in an Active Server Pages (ASP) or ASP.NET Web application. You try to access a variable in the Session object that you expect to exist, and it is null. You can also see this problem in a FRAMEs context if your Web pages alternate between the use of Domain Name System (DNS) names and the use of Internet Protocol (IP) addresses.

The fix is very simple - Starting in Internet Explorer 6 support for the Platform for Privacy Preferences (P3P) Project was introduced. The P3P standard notes that if a FRAMESET or a parent window references another site inside a FRAME or inside a child window, the child site is considered third party content. Internet Explorer, which uses the default privacy setting of Medium, silently rejects cookies sent from third party sites. So consequently a large percentage of your visitors may end up having an unhappy experience on your site.

You can add a P3P compact policy header to your child content, and you can declare that no malicious actions are performed with the data of the user. If Internet Explorer detects a satisfactory policy, then Internet Explorer permits the cookie to be set. Most developers that have hosted sites don't have the ability to access IIS and set the required header.

An easy fix is to add the header in Global.asax:

protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("p3p", "CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");

}

A simple compact policy that fulfills the needed criteria follows:

P3P: CP="CAO PSA OUR"

The above code sample shows that your site provides you access to your own contact information (CAO), that any analyzed data is only "pseudo-analyzed", which means that the data is connected to your online persona and not to your physical identity (PSA), and that your data is not supplied to any outside agencies for those agencies to use (OUR). This is sufficient to get Internet Explorer (and some other browsers) to allow the Session cookie, as well as other cookies.

This page provides more information about the P3P privacy policy for Internet Explorer.

To summarize: unsatisfactory cookies are those where the policy contains a token from both columns in the table below and where the purpose/recipient token does not contain the optional attributes, "i" or "o." As an example, a cookie with a compact policy that contains the tokens PHY and OTR is an unsatisfactory cookie, whereas a cookie with the compact policy that contains PHY and OTRo is acceptable.

CategoryPurpose/Recipient
PHY Physical location
ONL Online location
GOV Government ID
FIN Financial information
SAM Same policies
OTR Other recipients
UNR Unknown purposes
PUB Publicly available
IVA Individual Analysis
IVD Individual Decision
CON Contact Information
TEL Telephone Promotion
OTP Other Purposes

If you've been having Session or other cookie issues and you have any kind of frames on your pages, try this fix. Even if it does not solve the problem, it cannot hurt.

NOTE: This fix will NOT fix the security issue with denied access to content in an IFRAME or FRAME whose content is loaded from a different domain. That is by design, and I've railed about how hypocritical it is since you can have a client-side script tag whose src property points to anywhere at all, and browsers will happily slurp it up. That's why so many developers have turned to dynamically written script tags using JSON to marshal their results back into the browser DOM in the page.

Comments

  1. Anonymous6:22 AM

    Thanks for this. Excellent timing, I've been wrestling with the problem for a couple of days and this has fixed it! :)

    ReplyDelete
  2. Anonymous8:29 AM

    Very valuable information! Thanks alot for sharing!

    ReplyDelete
  3. Anonymous1:01 AM

    Thanks for the great article.
    But how do I implement this for ASP pages?

    What I do now is to add the third-party site to the sites allowed to use cookies in IE. This allows the webpage called in the frame to work properly with sessions/cookies.

    ReplyDelete
  4. Anonymous9:13 AM

    Thankyou, thankyou, thankyou!

    This little snippet saved me a lot of wasted time and effort (and a potential redesign of my architechture!)

    By the way to implement in classic ASP use this:

    Response.AddHeader "p3p", "CP=\""IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"

    Works a charm!

    Did I say thanks by the way!

    GS

    ReplyDelete
  5. Anonymous2:41 PM

    Perfect timing for me as well. I've been wrestling with this for the past 3 days wondering where my code went wrong with just IE and not Firefox.

    Thanks!

    ReplyDelete
  6. Anonymous4:31 PM

    Hi,

    Thanks alot!!! Really helpful!

    For people who need help with PHP you can look at:

    http://james.jamesandkristin.net/2005/11/18/php-session-cookie-in-frames-using-internet-explorer/#comment-55622

    Cheers

    /isak

    ReplyDelete
  7. Anonymous4:43 AM

    Great suggestion. It works in ASP also: in Global.asa, sub Session_OnStart, just add the following line:
    Response.AddHeader "p3p", "CP=""IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"""

    HTH
    cheers
    Luca

    ReplyDelete
  8. Anonymous4:35 AM

    Can we solve 'session loss' issue with iframes using hidden variables or URL rewriting?

    ReplyDelete
  9. Anonymous2:15 PM

    I had the same problem; login worked with Firefox and all other browsers, not with IE.
    It didn't work in IE on www.mysite.com but worked in IE on http://mysite.com.mywebfarm.myprovider.com

    After days of trying everything, and with a little modification on this HttpModule I finally got it working by redirecting the users to the second domain immediately. Instead of using
    ...AddHeader("p3p, "CP=...)

    I used:
    string url = context.Request.RawUrl;
    if (url.IndexOf("mywebfarm") < 1)
    {
    context.Response.Status = "301 Moved Permanently";
    context.Response.AddHeader("Location", "http://mysite.com.mywebfarm.myprovider.com");
    }

    This way my users could still use www.mysite.com but where in fact working on the subdomain without loss of the session/cookies...

    ReplyDelete
  10. This fixed a fairly critical bug. Thanks, Peter Bromberg, and, as always, thanks to Google even though they're taking over the world and they help China sensor information.

    ReplyDelete
  11. its not working for me :(
    I have tried to add
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
    HttpContext.Current.Response.AddHeader("p3p", "CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");

    }

    in global.asax and reset IIS but it didnt worked for me..any help?

    ReplyDelete

Post a Comment

Popular posts from this blog

Some observations on Script Callbacks, "AJAX", "ATLAS" "AHAB" and where it's all going.

IE7 - Vista: "Internet Explorer has stopped Working"

FIREFOX / IE Word-Wrap, Word-Break, TABLES FIX