diff --git a/dash/dash-renderer/src/actions/index.js b/dash/dash-renderer/src/actions/index.js index f54c0ed2af..247c2cea59 100644 --- a/dash/dash-renderer/src/actions/index.js +++ b/dash/dash-renderer/src/actions/index.js @@ -3,7 +3,7 @@ import {createAction} from 'redux-actions'; import {addRequestedCallbacks} from './callbacks'; import {getAppState} from '../reducers/constants'; import {getAction} from './constants'; -import * as cookie from 'cookie'; +import {parseCookie} from 'cookie'; import {validateCallbacksToLayout} from './dependencies'; import { includeObservers, @@ -77,7 +77,7 @@ export function getCSRFHeader(config) { try { const tokenName = (config && config.csrf_token_name) || '_csrf_token'; const headerName = (config && config.csrf_header_name) || 'X-CSRFToken'; - const cookies = cookie.parse(document.cookie); + const cookies = parseCookie(document.cookie); const token = cookies[tokenName]; if (!token) { return {}; diff --git a/tests/integration/security/test_csrf.py b/tests/integration/security/test_csrf.py new file mode 100644 index 0000000000..c840f64c6a --- /dev/null +++ b/tests/integration/security/test_csrf.py @@ -0,0 +1,21 @@ +import flask + +from dash import Dash, Input, Output, html + + +def test_csrf001_token_cookie_sent_as_header(dash_duo): + app = Dash(__name__) + app.layout = html.Div([html.Button("go", id="go"), html.Div(id="out")]) + + @app.server.after_request + def set_token(response): + response.set_cookie("_csrf_token", "tok123") + return response + + @app.callback(Output("out", "children"), Input("go", "n_clicks")) + def echo(_): + return flask.request.headers.get("X-CSRFToken", "missing") + + dash_duo.start_server(app) + dash_duo.wait_for_text_to_equal("#out", "tok123") + assert dash_duo.get_logs() == []