Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: disable cookie access under restricted sandboxes #1080

Merged
merged 9 commits into from
Jan 29, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
12 changes: 9 additions & 3 deletions dash-renderer/src/AccessDenied.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ 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) {
/* eslint-disable-next-line no-console */
console.warn(e);
}
window.location.reload(true);
}}
>
Expand Down
12 changes: 9 additions & 3 deletions dash-renderer/src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,15 @@ 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) {
/* eslint-disable-next-line no-console */
console.warn(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 len(dash_duo.get_logs()) == 2
Copy link
Contributor

@Marc-Andre-Rivet Marc-Andre-Rivet Jan 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josegonzalez The ==2 part is brittle but ok for now I think -- if you could open an issue to improve this part of the test later, I'm fine as-is. What I would like so see here is some validation that the Dash app actually loaded and works as expected. Maybe select the #btn, click it, and make sure at least one of the divs got updated by the callback.