Safari Intelligent Tracking Prevention: Configuring Third‑Party Storage Access After Interaction Timer Expires
0 reputation · 15 Oct 2024, 10:32 UTC
0 reputation · 15 Oct 2024, 10:32 UTC
Design a strategy that ensures third‑party services can reliably access cookies and local storage after Safari’s Intelligent Tracking Prevention (ITP) interaction timer has elapsed.
Safari partitions third‑party data until the user performs a qualifying top‑level interaction. The timer’s remaining duration is not exposed via any public JavaScript API, and there is no documented way to programmatically reset it. Interaction must occur on the top‑level page; embedded iframes do not restart the timer. The behavior differs between macOS and iOS and may change without migration guidance.
Because developers cannot query the timer or force a reset, it is unclear how to detect when a third‑party cookie is blocked and how to design a graceful fallback that works consistently across Safari releases.
35275 reputation · 15 Oct 2024, 11:16 UTC
There is no supported JavaScript API to read, extend, or reset Safari's ITP interaction timer. Once expired, third-party cookies and localStorage remain partitioned until a qualifying top-level user interaction occurs. Detection relies on probing storage access, and recovery requires real user gestures.
Without a timer API, detection must be empirical:
document.hasStorageAccess() and document.requestStorageAccess() from the iframe. A rejected promise or false result signals blocked access, though this does not distinguish ITP from total cookie blocking.SecurityError or QuotaExceededError when writing to localStorage, which may indicate partitioned storage.Always compare with a first-party control to avoid false positives from private browsing or global cookie blocking.
Only specific top-level interactions reset the timer. Reliable patterns include:
Platform differences: macOS and iOS behavior varies by Safari version. Test on target releases; older gestures may no longer work after WebKit updates.
Design for failure, not persistence:
requestStorageAccess(). Handle rejection by degrading functionality.Avoid anti-patterns: Do not simulate clicks, auto-retry storage access, or repeatedly prompt users. These may violate platform policies and fail in future WebKit releases.
Before deploying, validate behavior on current Safari versions:
// In third-party iframe: set and check storage
localStorage.setItem('itp_probe', 'test');
console.log(localStorage.getItem('itp_probe')); // null = partitioned
// After top-level interaction, test access
window.addEventListener('message', (e) => {
if (e.data.type === 'user_clicked') {
document.requestStorageAccess().then(() => {
console.log('Access granted');
}).catch(() => {
console.log('Access denied - use fallback');
});
}
});
Use Web Inspector on macOS or remote debugging on iOS to confirm storage partitioning and access grants across different settings (Block All Cookies, Cross-Site Tracking Prevention).
The exact interaction window duration and eligible gestures are not part of any public API contract. Apple may change these without notice. Always test against the latest Safari release before relying on specific behavior.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.