Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Safari iframe cookie workaround
<?php
header("Location: " . $_GET['redirect']);
setcookie("__trust");
<?php
if (!isset($_COOKIE['testcookie']))
echo "Cookie not set!";
else if ($_COOKIE['testcookie'] != $_GET['cookie'])
echo "Cookies don't match: " . $_COOKIE['testcookie'] . ' != ' . $_GET['cookie'];
else
echo "Cookies match!";
<?php
$value = uniqid();
setcookie("testcookie", $value);
echo "<p>Now go <a href='dest_get.php?cookie=" . $value . "'>here</a></p>";
<?php
$internalPath = "http://local.test/path";
$externalPath = "http://remote.test/path";
?>
<html><head><title>Redirect Cookie Test</title></head>
<body>
<?php if ($_GET['redirected']): ?>
<p>iframe starts below...</p>
<iframe src="<?= $externalPath ?>/dest_set.php"?>
<?php else: ?>
<a href="<?= $externalPath ?>/dest_bounce.php?redirect=<?= $internalPath ?>/src.php?redirected=true">Bounce here...</a>
<?php endif; ?>
</body>
@kevinvos

This comment has been minimized.

Copy link

kevinvos commented Oct 27, 2017

Nice catch, thanks for the explanation! I've discovered the same problem which magically solved itself, now I know why and how :).

@RaiserWeb

This comment has been minimized.

Copy link

RaiserWeb commented Nov 20, 2017

This indeed works. One issue it presents is that Google Analytics tracking is lost, and counts the visit as being referred from the remote.test domain. I'm trying to work out how to get GA to ignore this redirection but no luck thus far.

@mattharley

This comment has been minimized.

Copy link

mattharley commented Nov 29, 2017

Unsure if this still works but there is a Javasctipt-only solution https://github.com/vitr/safari-cookie-in-iframe

Works on the same principal but does the redirect on the page underneath the iFrame without needing to hit the server.

@Enalmada

This comment has been minimized.

Copy link

Enalmada commented Nov 30, 2017

I just put something in an iframe and was pulling my hair out that some users were reporting issues...turned out to be this. Thank you very much for taking the time to do this write up. Also very thankful for the "safari-cookie-in-iframe" reference....here is what I went with based on that:

PARENT

var is_safari = navigator.userAgent.indexOf("Safari") > -1;
// Chrome has Safari in the user agent so we need to filter (https://stackoverflow.com/a/7768006/1502448)
var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
if ((is_chrome) && (is_safari)) {is_safari = false;}  
if (is_safari) {
    // See if cookie exists (https://stackoverflow.com/a/25617724/1502448)
    if (!document.cookie.match(/^(.*;)?\s*fixed\s*=\s*[^;]+(.*)?$/)) {
        // Set cookie to maximum (https://stackoverflow.com/a/33106316/1502448)
        document.cookie = 'fixed=fixed; expires=Tue, 19 Jan 2038 03:14:07 UTC; path=/';
        window.location.replace("http://vit-demos.appspot.com/_safari_fix.html");
    }
}

CHILD

document.cookie = 'safari_cookie_fix=true; path=/';
window.location.replace(document.referrer);
@jloguercio

This comment has been minimized.

Copy link

jloguercio commented Jun 3, 2018

I can't make this work with the solution : https://github.com/vitr/safari-cookie-in-iframe , i create have an site B in a Iframe in A, so in A i write this code :

var is_safari = navigator.userAgent.indexOf("Safari") > -1;
// Chrome has Safari in the user agent so we need to filter (https://stackoverflow.com/a/7768006/1502448)
var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
if ((is_chrome) && (is_safari)) {is_safari = false;}  
if (is_safari) {
    // See if cookie exists (https://stackoverflow.com/a/25617724/1502448)
    if (!document.cookie.match(/^(.*;)?\s*fixed\s*=\s*[^;]+(.*)?$/)) {
        // Set cookie to maximum (https://stackoverflow.com/a/33106316/1502448)
        document.cookie = 'fixed=fixed; expires=Tue, 19 Jan 2038 03:14:07 UTC; path=/';
        window.location.replace("http://vit-demos.appspot.com/_safari_fix.html");
    }
}

and create a file called _safari_fix.html with this code :

document.cookie = 'safari_cookie_fix=true; path=/';
window.location.replace(document.referrer);

but the workaround doesn't work

@datthepirate

This comment has been minimized.

Copy link

datthepirate commented Jul 20, 2018

Does this still work in 2018?

@bktan81

This comment has been minimized.

Copy link

bktan81 commented Aug 1, 2018

tried and it works

@dawolf

This comment has been minimized.

Copy link

dawolf commented Aug 6, 2018

This stopped working for me with the latest Safari on macOS Version 11.1.2 (13605.3.8)

Session cookie in a iframe will be dropped if the domain in the iframe has not been visited before.

@fbricenho

This comment has been minimized.

Copy link

fbricenho commented Sep 20, 2018

I just put something in an iframe and was pulling my hair out that some users were reporting issues...turned out to be this. Thank you very much for taking the time to do this write up. Also very thankful for the "safari-cookie-in-iframe" reference....here is what I went with based on that:

PARENT

var is_safari = navigator.userAgent.indexOf("Safari") > -1;
// Chrome has Safari in the user agent so we need to filter (https://stackoverflow.com/a/7768006/1502448)
var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
if ((is_chrome) && (is_safari)) {is_safari = false;}  
if (is_safari) {
    // See if cookie exists (https://stackoverflow.com/a/25617724/1502448)
    if (!document.cookie.match(/^(.*;)?\s*fixed\s*=\s*[^;]+(.*)?$/)) {
        // Set cookie to maximum (https://stackoverflow.com/a/33106316/1502448)
        document.cookie = 'fixed=fixed; expires=Tue, 19 Jan 2038 03:14:07 UTC; path=/';
        window.location.replace("http://vit-demos.appspot.com/_safari_fix.html");
    }
}

CHILD

document.cookie = 'safari_cookie_fix=true; path=/';
window.location.replace(document.referrer);

Does this still working?

@ricklambrechts

This comment has been minimized.

Copy link

ricklambrechts commented Nov 7, 2018

The javascript workaround still works!

@shazadmaved

This comment has been minimized.

Copy link

shazadmaved commented Feb 23, 2019

With the javascript workaround, The first access gets into a redirect loop in safari :| , could anyone suggest something that must be wrong. The second access onwards it works fine. For some reason during the redirect the "fixed" cookie that is set is not being fetched.

@thomasdarde

This comment has been minimized.

Copy link

thomasdarde commented Apr 3, 2019

this solution is nice and works , but an important caveat is found if the page is called from a "post" url. The return won't work.
window.postmessage is a good solution to share data between iframe and parent.

@allenlinli

This comment has been minimized.

Copy link

allenlinli commented Apr 17, 2019

Should we fire a radar to Apple for this Safari feature(bug)?

@allenlinli

This comment has been minimized.

Copy link

allenlinli commented Apr 17, 2019

I think maybe we can't... https://discussions.apple.com/thread/4156939
I just can't figure what could iframe cookie threat users using Safari.

@SebT

This comment has been minimized.

Copy link

SebT commented Aug 1, 2019

The JS workaround works on MacOS but not on iOS (iPad). Does anyone have a similar problem ?

@raj-uimatic

This comment has been minimized.

Copy link

raj-uimatic commented Jan 3, 2020

My cookie does not carry forward data from one iframe to another in safari, I have a scenario like this:
I have parent domain ex: website.com , Inside that I have a iframe with this url ex. parent.com where I am setting cookie for parent while submitting form so I am setting cookie like this domain=".parent.com" (so it will set cookie for subdomain automatically)

When form is submitted I move to another page like website2.com and inside that page I have a iframe with subdomain like parent.child.com Now issue is I am not able to get cookie which were set by parent.com in safari

Please help! other browser works great

Thanks

@tgiordmaina

This comment has been minimized.

Copy link

tgiordmaina commented Mar 2, 2020

It seems safari is the new IE.. what a weird behavior, I'm tired, 3 days I tried to solve that, I need to rebuild all my authentication system because of that. TY apple, if anyone as a solution not a workaround it will be great. Thanks

@WebSpectrum

This comment has been minimized.

Copy link

WebSpectrum commented Mar 16, 2020

Hi All - what is the best solution to date if you don't have control or ability to deploy code on site B ? ....

@tgiordmaina

This comment has been minimized.

Copy link

tgiordmaina commented Mar 16, 2020

I used a popup to do the trick (by temporary passing the cookie as parameter to a third party API).
If you have full control on site B (code + DNS) I advice you to declare a subdomain in you site B which forward silently to your wished website/API (add a new AAAA entry with your service IP) :

       +------------------+                          +-----------------------+
       |                  |   XHR with credentials   |                       |
       |  www.siteB.com   --------------------------->  api-siteA.siteB.com  |
       |                  |                          |                       |
       +------------------+                          +-----------------------+
@russau

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.