Document possible impacts of disabling third-party cookies on front-channel logout
Contributors have described that their front-channel logout implementations do not work when third-party cookies are disabled. The working group should discuss this situation and at a minimum, document that front-channel logout may/will not work with third-party cookies disabled, and describe why this is the case. If it is possible to work around this situation, the work-arounds should also be described.
Comments (9)
-
-
A reference cookie based implementation of session management. This mitigates the unwanted behavior of endless re-authentications by the RP by returning error in scenarios where third party cookies are assumed block.
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>Session Management - OP iframe</title> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/2.2.0/sha256.js" integrity="sha256-cZOjfJHUnIR4AN0bIASJHvhhJudsombORNNWzHKVoXY=" crossorigin="anonymous"></script> </head> <body> <script type="application/javascript"> var debug = false; var thirdPartyCookies = true; function receiveMessage(e) { if (e.data === 'MM:3PCunsupported') { thirdPartyCookies = false; return; } else if (e.data === 'MM:3PCsupported') { return; } try { var message_parts = e.data.split(' '); var clientId = message_parts[0]; var actual = message_parts[1]; if (debug && console) console.log('OP recv session state: ' + actual); var salt = actual.split('.')[1]; var opbs = getOPBrowserState(clientId); var shaObj = new jsSHA('SHA-256', 'TEXT'); shaObj.update(clientId + ' ' + e.origin + ' ' + opbs + ' ' + salt); var expected = shaObj.getHash('HEX') + ['.' + salt]; if (debug && console) console.log('OP computed session state: ' + expected); var stat; if (actual === expected) { stat = 'unchanged'; } else { stat = 'changed'; } if (debug && console) console.log('OP status: ' + stat); e.source.postMessage(stat, e.origin); } catch (err) { e.source.postMessage('error', e.origin); } } function getOPBrowserState(clientId) { var cookie = readCookie('_state.' + clientId); if (debug && console) console.log('session state cookie: ' + cookie); if (!thirdPartyCookies && !cookie) throw new Error('third party cookies unsupported (detected)'); return cookie; } function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } window.addEventListener('message', receiveMessage, false); </script> <iframe src="https://cdn.rawgit.com/panva/3rdpartycookiecheck/92fead3f/start.html" style="display:none" /> </body> </html>
-
reporter -
assigned issue to
We should say that this will not always work but not try to definitively describe the current situation because it is likely to keep changing. Suggested text would be welcomed!
-
assigned issue to
-
reporter We should say that this will not always work but not try to definitively describe the current situation because it is likely to keep changing. Suggested text would be welcomed!
-
I think the priority of this should be increased now that Chrome is moving to SameSite=Lax by default (since SameSite cookies have the same effect as disabling third-party cookies).
-
reporter Mike will propose warning text in the Implementation Consideration sections of the Session and Front-Channel specs. Hopefully @gffletch will review it.
-
reporter I propose to add this Implementation Considerations text to the Front-Channel spec. @panva and @gffletch - please review:
Note that at the time of this writing, some User Agents (browsers) are starting to block access to third-party content by default to block some mechanisms used to track the End-User's activity across sites. Specifically, the third-party content being blocked is website content with an origin different that the origin of the focused User Agent window. Site data includes cookies and any web storage APIs (sessionStorage, localStorage, etc.).
This can prevent the ability for notifications from the OP at the RP from being able to access the RP's User Agent state to implement local logout actions. In particular, the <spanx style="verb">frontchannel_logout_uri</spanx> might not be able to access the RP's login state when rendered by the OP in an iframe because the iframe is in a different origin than the OP's page. Therefore, deployments of this specification are recommended to include defensive code to detect this situation, and if possible, notify the End-User that the requested RP logouts could not be performed. The details of the defensive code needed are beyond the scope of this specification; it may vary per User Agent and may vary over time, as the User Agent tracking prevention situation is fluid and continues to evolve.
<xref target="OpenID.BackChannel">OpenID Connect Back-Channel Logout 1.0</xref> is not known to be affected by these developments.
I likewise propose to add this similar Implementation Considerations text to the Session spec:
Note that at the time of this writing, some User Agents (browsers) are starting to block access to third-party content by default to block some mechanisms used to track the End-User's activity across sites. Specifically, the third-party content being blocked is website content with an origin different that the origin of the focused User Agent window. Site data includes cookies and any web storage APIs (sessionStorage, localStorage, etc.).
This can prevent the ability for notifications from the OP at the RP from being able to access the RP's User Agent state to implement local logout actions. In particular,
cookies and web storage APIs may not be available in the OP frame loaded in the RP context. The side effect here is that, depending on the used mechanism (cookies or web storage), the data needed to recalculate <spanx style="verb">session_state</spanx> might not be available. Cookie based implementations might then return <spanx style="verb">changed</spanx> for every single call, resulting in infinite loops of re-authentications. Therefore, deployments of this specification are recommended to include defensive code to detect this situation, and if possible, notify the End-User that the requested RP logouts could not be performed. The details of the defensive code needed are beyond the scope of this specification; it may vary per User Agent and may vary over time, as the User Agent tracking prevention situation is fluid and continues to evolve.<xref target="OpenID.BackChannel">OpenID Connect Back-Channel Logout 1.0</xref> is not known to be affected by these developments.
-
@Michael Jones works for me!
-
reporter - changed status to resolved
Fixed
#1003- Document possible impacts of disabling access to third-party content→ <<cset f4cefe46ea80>>
- Log in to comment
First and foremost, this does not only affect Front-Channel, by my findings Session Management is affected too.
The problem comes when User-Agents block access to third party site data. For the sake of simplicity third party means a website content (in our case an iframe) with origin different than the one of the focused User-Agent window. Site data includes Cookies and any Web Storage API (sessionStorage, localStorage).
When do User-Agents block this access?
Most commonly this behavior is disabled by default and must be explicitly enabled by the End-User. Some browsers (most notably Internet Explorer on Medium-High privacy setting) come with pre-sets that already block this access and on some mobile browsers this is already default (i was not able to confirm, but iOS safari recent versions)
How is this block implemented?
This differs from browser to browser and from type of data too. Web Storage APIs may throw an Exception when trying to access the getters, they might also return undefined instead. Cookies (accessed both via javascript or when (not) sent to the browser with the request in question) are simply not present / are undefined. There is heavy inconsistency in the implementation of Web Storage API blocks when it comes to browser distributions. Firefox and Chrome both throw an instance of SecurityError when trying to access the API, other browsers in their current state either don't block this access yet or their block mechanism cannot be relied upon. There is also inconsistency in the Cookie block implementations, some browsers include options to only enforcing block for non-visited websites, some seem to imply this rule.
When this User-Agent feature is enabled, how is OpenID Connect affected?
Recommendation
Due to the inconsistency in implementations i ended up attempting to read the data anyway (my implementation is cookie based) and have a detection mechanism for this in place (https://github.com/mindmup/3rdpartycookiecheck). So in cases where the expected data was not there and a detection mechanism returned true, i return 'error' as per the specification to tell the RP not to do a re-authentication.
session management - RPs should be encouraged to perform a detection of this on their own and skip loading the OP and RP frames in those cases, they should be warned that this may result in a chain of endless re-authentications due to the possibly returned "changed" state.
front-channel logout - RPs should be informed that this mechanism is not 100%, should be encouraged to always implement both front and back channels should the OP support it as there is no workaround for the issue.