views:

10928

answers:

9

I have two websites, let's say they're example.com and anotherexample.net. On anotherexample.net/page.html, I have an IFRAME SRC="http://example.com/someform.asp". That IFRAME displays a form for the user to fill out and submit to http://example.com/process.asp. When I open the form ("someform.asp") in its own browser window, all works well. However, when I load someform.asp as an IFRAME in IE 6 or IE 7, the cookies for example.com are not saved. In Firefox this problem doesn't appear.

For testing purposes, I've created a similar setup on http://newmoon.wz.cz/test/page.php .

example.com uses cookie-based sessions (and there's nothing I can do about that), so without cookies, process.asp won't execute. How do I force IE to save those cookies?

Results of sniffing the HTTP traffic: on GET /someform.asp response, there's a valid per-session Set-Cookie header (e.g. Set-Cookie: ASPKSJIUIUGF=JKHJUHVGFYTTYFY), but on POST /process.asp request, there is no Cookie header at all.

Edit3: some AJAX+serverside scripting is apparently capable to sidestep the problem, but that looks very much like a bug, plus it opens a whole new set of security holes. I don't want my applications to use a combination of bug+security hole just because it's easy.

Edit: the P3P policy was the root cause, full explanation below.

+31  A: 

I got it to work, but the solution is a bit complex, so bear with me.

What's happening

As it is, Internet Explorer gives lower level of trust to IFRAME pages (IE calls this "third-party" content). If the page inside the IFRAME doesn't have a Privacy Policy, its cookies are blocked (which is indicated by the eye icon in status bar, when you click on it, it shows you a list of blocked URLs).

the evil eye

In this case, when cookies are blocked, session identifier is not sent, and the target script throws a 'session not found' error.

(I've tried setting the session identifier into the form and loading it from POST variables. This would have worked, but for political reasons I couldn't do that.)

It is possible to make the page inside the IFRAME more trusted: if the inner page sends a P3P header with a privacy policy that is acceptable to IE, the cookies will be accepted.

How to solve it

Create a p3p policy

A good starting point is the W3C tutorial. I've gone through it, downloaded the IBM Privacy Policy Editor and there I created a representation of the privacy policy and gave it a name to reference it by (here it was policy1).

NOTE: at this point, you actually need to find out if your site has a privacy policy, and if not, create it - whethere it collects user data, what kind of data, what it does with it, who has access to it, etc. You need to find this information and think about it. Just slapping together a few tags will not cut it. This step cannot be done purely in software, and may be highly political (e.g. "should we sell our click statistics?").

(e.g. "the site is operated by ACME Ltd., it uses anonymous per-session identifiers for its operation, collects user data only if explicitly permitted and only for the following purposes, the data is stored only as long as necessary, only out company has access to it, etc. etc.").

(When editing with this tool, it's possible to view errors/omissions in the policy. Also very useful is the tab "HTML Policy": at the bottom, it has a "Policy Evaluation" - a quick check if the policy will be blocked by IE's default settings)

The Editor exports to a .p3p file, which is an XML representation of the above policy. Also, it can export a "compact version" of this policy.

Link to the policy

Then a Policy Reference file (http://example.com/w3c/p3p.xml) was needed (an index of privacy policies the site uses):

<META>
  <POLICY-REFERENCES>
    <POLICY-REF about="/w3c/example-com.p3p#policy1">
      <INCLUDE>/</INCLUDE>
      <COOKIE-INCLUDE/>
    </POLICY-REF>
  </POLICY-REFERENCES>
</META>

The <INCLUDE> shows all URIs that will use this policy (in my case, the whole site). The policy file I've exported from the Editor was uploaded to http://example.com/w3c/example-com.p3p

Send the compact header with responses

I've set the webserver at example.com to send the compact header with responses, like this:

HTTP/1.1 200 OK 
P3P: policyref="/w3c/p3p.xml", CP="IDC DSP COR IVAi IVDi OUR TST"
// ... other headers and content

policyref is a relative URI to the Policy Reference file (which in turn references the privacy policies), CP is the compact policy representation. Note that the combination of P3P headers in the example may not be applicable on your specific website; your P3P headers MUST truthfully represent your own privacy policy!

Profit!

In this configuration, the Evil Eye does not appear, the cookies are saved even in the IFRAME, and the application works.

Edit: What NOT to do, unless you like defending from lawsuits

Several people have suggested "just slap some tags into your P3P header, until the Evil Eye gives up".

The tags are not only a bunch of bits, they have real world meanings, and their use gives you real world responsibilities!

For example, pretending that you never collect user data might make the browser happy, but if you actually collect user data, the P3P is conflicting with reality. Plain and simple, you are purposefully lying to your users, and that might be criminal behavior in some countries. As in, "go to jail, do not collect $200".

A few examples (see p3pwriter for the full set of tags):

  • NOI : "Web Site does not collected identified data." (as soon as there's any customization, a login, or any data collection (***** Analytics, anyone?), you must acknowledge it in your P3P)
  • STP: Information is retained to meet the stated purpose. This requires information to be discarded at the earliest time possible. Sites MUST have a retention policy that establishes a destruction time table. The retention policy MUST be included in or linked from the site's human-readable privacy policy." (so if you send STP but don't have a retention policy, you may be committing fraud. How cool is that? Not at all.)

I'm not a lawyer, but I'm not willing to go to court to see if the P3P header is really legally binding or if you can promise your users anything without actually willing to honor your promises.

Piskvor
I was 95% complete, but my header only said: P3P: CP="...." and didn't include the policyref link, which made it work in IE7, but not IE6... works good now. Thanks!
AndreasKnudsen
A: 

A better solution would be to make an Ajax call inside the iframe to the page that would get/set cookies...

Luca Matteis
AJAX won't help here: *any* cookie handling inside the iframe is less trusted ("third-party cookies"), and in IE needs to pass through the Privacy Policy filter - no matter if you're setting cookies with AJAX calls, document.cookie manipulation or through normal pages (tested).
Piskvor
no, if you're make an ajax call that sets the cookies with HTTP (inside the iframe) Ie6 bypasses the security policy and sets the cookie. Please assure my solution is wrong before downvoting.
Luca Matteis
See http://newmoon.wz.cz/test/page.php .You can set cookies via AJAX, but you either a)start new session, or b)set session id from JS - a *huge* security hole (XSRF).My previous comment was wrong,I apologize.But,your solution looks wronger than before: *making* a security hole seems bad to me.
Piskvor
(Anything that "bypasses security policy" looks *at least* like a bug to me - if there is a policy, it's there for some reason. Saying "screw the security policy/user preferences, we know better" is a dangerous slippery slope. Also, would you let functionality depend on (yet) unfixed known bugs?)
Piskvor
Set a new session? What are you talking about? Most browser support this, without the p3p header stuff, so I don't understand how doing it through Ajax is any different...
Luca Matteis
Indeed,most browsers support this,but I can't force the users to switch.Anyway,check the test page:if you AJAX a request to set_cookie.php,the session ID will be different from the ID you see on someform.php.Requesting set_cookie.php?sid={something} will work,but will work from any site.Not optimal.
Piskvor
I dont have ie6 to test on right now, but why would the session ID be different using Ajax? Anyhow on a different note I'm using "script" tags to **SET** cookies (not iframes), but I can't seem to make it work in Safari, were you able to **SET** cookies in Safari with this IFRAME method?
Luca Matteis
I finished my characters, check this link out: http://stackoverflow.com/questions/408582/setting-cross-domain-cookies-in-safari
Luca Matteis
Hmmm, Safari? I'll give it a try.
Piskvor
+1  A: 

One possible thing to do is to add the domain to allowed sites in tools -> internet options -> privacy -> sites: somedomain.com -> allow -> OK.

heikkim
Yes, if you only care that it works on your computer. Not entirely practical to suggest this to every visitor.
Piskvor
+2  A: 

Got similar problem, also went to investigate how to generate the P3P policy this morning, here is my post about how to generate your own policy and use in the web site :) http://everydayopenslikeaflower.blogspot.com/2009/08/how-to-create-p3p-policy-and-implement.html

Ping
A: 

is there any way to achieve this? like using alternative to iframe if exist?

Please post questions as questions. If it has a "?" at the end, it's probably not an answer.
Piskvor
+1  A: 

This article was really helpful.

I had a session cookie problem in an Iframe in IE.

In case it helps anyone, these were the settings that I used after I generated the policy:

My p3p.xml file was this:

<META>
  <POLICY-REFERENCES>
    <POLICY-REF about="/w3c/privacy_policy.p3p">
       <INCLUDE>http://full_path_to_domain/*&lt;/INCLUDE&gt; 
       <COOKIE-INCLUDE name="*" value="*" domain="*" path="*" /> 
    </POLICY-REF>
  </POLICY-REFERENCES>
</META>

To send the headers I used this in .htaccess:

<IfModule mod_headers.c>
Header set P3P "policyref=\"http://full_pathway_to_/w3c/p3p.xml\", CP=\"ALL DSP COR CURa ADMa DEVa TAIa IVAi IVDi CONi HISi TELi OUR IND PHY ONL FIN COM NAV INT DEM GOV\""
</IfModule>

All files in a /w3c/ folder in the root.

Happy days.

Elchoco
A: 

Does anyone know of a way of addressing this issue when you don't have access to change the 3rd party web pages which you're pulling into the iframe?

We're working on an application which pulls a payment gateway page into an iframe. However the cookies used by the payment gateway are blocked. Is this an issue that we can resolve or is it an issue for the payment gateway company to address?

Many thanks.

Rob MacDonald
Briefly: Whatever is *inside* the iframe needs to have P3P - in this case, the payment gateway must do that.
Piskvor
A: 

I was able to make the evil eye go away by simply adding this small header to the site in the IFrame (PHP solution):

header('P3P: CP="NOI ADM DEV COM NAV OUR STP"');

Remember to press ctrl+F5 to reload your site or Explorer may still show the evil eye, despite the fact that it's working fine. This is probably the main reason why I had so many problems getting it to work.

No policy file was neccesary at all.

Helo
IANAL, but the P3P policy seems to be legally binding. Are you *aware* what you're promising to the users here, or did you just mix tags until the EvilEye disappeared? I think browser caching won't be your biggest problem with these: "**NOI**: Web Site does not collect identified data. **STP**: Information is retained to meet the stated purpose. This requires information to be discarded at the earliest time possible. Sites MUST have a retention policy that establishes a destruction time table. The retention policy MUST be included in or linked from the site's human-readable privacy policy."
Piskvor
I must admit that I dont really care what it means, I just needed stuff to work in Explorer. The sites are our own non-public sites one of which uses a cookie to 'remember' which style to show the site in.So, yes, I just mixed tags until the evil eye disappeared.
Helo
+2  A: 

This is a great topic on the issue, however I found that one important detail (which was essential at least in my case) that was not posted here or anywhere else (I apologize if I just missed it) was that the P3P line must be passed in header of EVERY file sent from the 3rd party server, even files not setting or using the cookies such as Javascript files or images. Otherwise the cookies will be blocked. I have more on this in a post here: http://posheika.net/?p=110

Juris
Hmmm, never thought of that. Good point!
Piskvor