From 26d8641d1ec2a011c169f14a0354640028930ff2 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 10 Jan 2020 19:41:07 -0500 Subject: [PATCH 1/3] feat: disable cookie access under restricted sandboxes When dash is embedded into an iframe with a sandbox attribute that only has allow-scripts, cookie access is disabled and dash-table fails to load. As such, we need to restrict our cookie usage by disabling functionality. This patch removes the disabled functionality in a graceful manner, allowing dash-table to load in very restricted iframes. --- src/core/storage/Cookie.ts | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/core/storage/Cookie.ts b/src/core/storage/Cookie.ts index b06db4ce3..a135c2ef8 100644 --- a/src/core/storage/Cookie.ts +++ b/src/core/storage/Cookie.ts @@ -2,7 +2,31 @@ const __1day = 86400 * 1000; const __20years = 86400 * 1000 * 365 * 20; export default class CookieStorage { + public static enabled() { + // From https://github.com/Modernizr/Modernizr/blob/f4d3aa0b3c9eeb7338e8d89ed77929a8e969c502/feature-detects/cookies.js#L1 + // try..catch because some in situations `document.cookie` is exposed but throws a + // SecurityError if you try to access it; e.g. documents created from data URIs + // or in sandboxed iframes (depending on flags/context) + + try { + // Create cookie + document.cookie = 'cookietest=1'; + let ret = document.cookie.indexOf('cookietest=') !== -1; + // Delete cookie + document.cookie = 'cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT'; + return ret; + } catch (e) { + return false; + } + + return false; + } + public static delete(id: string, domain: string = '', path: string = '/') { + if (!CookieStorage.enabled()) { + return; + } + let expires = new Date(Date.now() - __1day).toUTCString(); document.cookie = `${id}=;expires=${expires};domain=${domain};path=${path}`; @@ -13,6 +37,10 @@ export default class CookieStorage { return; } + if (!CookieStorage.enabled()) { + return; + } + id = id.toLowerCase(); let cookies = document.cookie.split(';').map(cookie => { @@ -28,6 +56,10 @@ export default class CookieStorage { } public static set(id: string, value: string, domain: string = '', path: string = '/') { + if (!CookieStorage.enabled()) { + return; + } + let expires = new Date(Date.now() + __20years).toUTCString(); let entry = `${id}=${value};expires=${expires};domain=${domain};path=${path}`; @@ -38,4 +70,4 @@ export default class CookieStorage { document.cookie = entry; } -} \ No newline at end of file +} From 76f4e143c5b1cfa9dafcdf86298ff5644a00fa83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Tue, 14 Jan 2020 09:02:04 -0500 Subject: [PATCH 2/3] Execute CookieStorage.enabled only once --- src/core/storage/Cookie.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/core/storage/Cookie.ts b/src/core/storage/Cookie.ts index a135c2ef8..ebe72ad41 100644 --- a/src/core/storage/Cookie.ts +++ b/src/core/storage/Cookie.ts @@ -1,13 +1,14 @@ +import * as R from 'ramda'; + const __1day = 86400 * 1000; const __20years = 86400 * 1000 * 365 * 20; export default class CookieStorage { - public static enabled() { - // From https://github.com/Modernizr/Modernizr/blob/f4d3aa0b3c9eeb7338e8d89ed77929a8e969c502/feature-detects/cookies.js#L1 - // try..catch because some in situations `document.cookie` is exposed but throws a - // SecurityError if you try to access it; e.g. documents created from data URIs - // or in sandboxed iframes (depending on flags/context) - + // From https://github.com/Modernizr/Modernizr/blob/f4d3aa0b3c9eeb7338e8d89ed77929a8e969c502/feature-detects/cookies.js#L1 + // try..catch because some in situations `document.cookie` is exposed but throws a + // SecurityError if you try to access it; e.g. documents created from data URIs + // or in sandboxed iframes (depending on flags/context) + public static enabled = R.once((): boolean => { try { // Create cookie document.cookie = 'cookietest=1'; @@ -18,9 +19,7 @@ export default class CookieStorage { } catch (e) { return false; } - - return false; - } + }); public static delete(id: string, domain: string = '', path: string = '/') { if (!CookieStorage.enabled()) { From b15a35aee46f14450b6a9ff3f6d3041b185ee58c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Rivet?= Date: Tue, 14 Jan 2020 09:08:01 -0500 Subject: [PATCH 3/3] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81f26ef29..062060f33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - [#670](https://github.com/plotly/dash-table/pull/670) Fix a bug where `derived_filter_query_structure` was not getting updated properly +- [#677](https://github.com/plotly/dash-table/pull/677) Fix a bug where the table fails to load when used inside an iframe with a sandbox attribute that only has allow-scripts ## [4.5.1] - 2019-11-14 ### Fixed