Skip to content

Commit

Permalink
feat: disable cookie access under restricted sandboxes
Browse files Browse the repository at this point in the history
When dash is embedded into an iframe with a sandbox attribute that only has allow-scripts, cookie access is disabled and dash 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 to load in very restricted iframes.
  • Loading branch information
josegonzalez committed Jan 16, 2020
1 parent a9db3a0 commit 6d9660c
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
All notable changes to `dash` will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Fixed
- [#1080](https://github.com/plotly/dash/pull/1080) Handle case where dash fails to load when used inside an iframe with a sandbox attribute that only has allow-scripts

## [1.8.0] - 2020-01-14
### Added
- [#1073](https://github.com/plotly/dash/pull/1073) Two new functions to simplify usage handling URLs and pathnames: `app.get_relative_path` & `app.trim_relative_path`.
Expand Down
9 changes: 6 additions & 3 deletions dash-renderer/src/AccessDenied.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ function AccessDenied(props) {
<a
style={styles.base.a}
onClick={() => {
document.cookie =
`${constants.OAUTH_COOKIE_NAME}=; ` +
'expires=Thu, 01 Jan 1970 00:00:01 GMT;';
/* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
try {
document.cookie =
`${constants.OAUTH_COOKIE_NAME}=; ` +
'expires=Thu, 01 Jan 1970 00:00:01 GMT;';
} catch (e) {}
window.location.reload(true);
}}
>
Expand Down
10 changes: 7 additions & 3 deletions dash-renderer/src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@ export function hydrateInitialOutputs() {
}

export function getCSRFHeader() {
return {
'X-CSRFToken': cookie.parse(document.cookie)._csrf_token,
};
try {
return {
'X-CSRFToken': cookie.parse(document.cookie)._csrf_token,
};
} catch (e) {
return {};
}
}

function triggerDefaultState(dispatch, getState) {
Expand Down
51 changes: 51 additions & 0 deletions tests/integration/renderer/test_iframe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from multiprocessing import Value

import dash
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate

import dash_html_components as html


def test_rdif001_sandbox_allow_scripts(dash_duo):
app = dash.Dash(__name__)
call_count = Value("i")

N_OUTPUTS = 50

app.layout = html.Div([
html.Button("click me", id="btn"),
] + [html.Div(id="output-{}".format(i)) for i in range(N_OUTPUTS)])

@app.callback(
[Output("output-{}".format(i), "children") for i in range(N_OUTPUTS)],
[Input("btn", "n_clicks")]
)
def update_output(n_clicks):
if n_clicks is None:
raise PreventUpdate

call_count.value += 1
return ["{}={}".format(i, i + n_clicks) for i in range(N_OUTPUTS)]

@app.server.after_request
def apply_cors(response):
response.headers["Access-Control-Allow-Origin"] = "*"
response.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept, Authorization"
return response

dash_duo.start_server(app)

iframe = """
<!DOCTYPE html>
<html>
<iframe src="{0}" sandbox="allow-scripts">
</iframe>
</html>
"""

html_content = iframe.format(dash_duo.server_url)

dash_duo.driver.get("data:text/html;charset=utf-8," + html_content)

assert not dash_duo.get_logs()

0 comments on commit 6d9660c

Please sign in to comment.