-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
DashRenderer initialization and CSP #630
Comments
Hello, can you tell me please how can i create a hash for dash generated script? I use this lib as python package with django and CSP. Thks |
Not entirely sure what you mean with "dash generated script", but maybe this helps: In our Dash based project, we use something along these lines to calculate CSP hashes for all inline scripts (the import hashlib
import base64
from typing import List
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from flask_talisman import Talisman
def calculate_inline_hashes(app: dash.Dash) -> List[str]:
"""Given a Dash app instance, this function calculates
CSP hashes (sha256 + base64) of all inline scripts, such that
one of the biggest benefits of CSP (banning general inline scripts)
can be utilized.
Warning: Note that this function uses a "private" Dash app attribute,
app._inline_scripts, which might change from one Dash version to the next.
"""
return [
f"'sha256-{base64.b64encode(hashlib.sha256(script.encode('utf-8')).digest()).decode('utf-8')}'"
for script in [app.renderer] + app._inline_scripts
]
app = dash.Dash()
app.layout = html.Div(
[dcc.Input(id="my-id", value="initial value", type="text"), html.Div(id="my-div")]
)
app.clientside_callback(
"""
function(input) {
return "You have entered: " + input;
}
""",
Output(component_id="my-div", component_property="children"),
[Input(component_id="my-id", component_property="value")],
)
csp = {
"default-src": "'self'",
"script-src": ["'self'"] + calculate_inline_hashes(app),
"style-src": ["'self'", "'unsafe-inline'"],
}
Talisman(app.server, content_security_policy=csp, force_https=False)
if __name__ == "__main__":
app.run_server(debug=True) |
Thks this help me! |
That very much depends on which components you use in your Dash application (e.g. If you make your own Dash components, you can ensure you don't need |
@anders-kiaer how are you dealing with dcc.graph() under this approach? Calculating CSP hashes appears to be working for everything except dcc.graph() |
Not sure if you are talking about CSP hashes of inline |
inline js, I'll re-explore the issue, what version of dash and dash-core-components are you on? |
@PoSeyy I am also experiencing this issue. Are you still investigating this? I am using the following versions. dash 1.12.0 |
@rpmchale Couldn't solve this one, still interested in finding a solution, just not actively investigating. |
@rpmchale is the dcc.graph that you are map? |
Dash is a CSP friendly framework, enabling writing XSS safe applications, however this had a setback in #367.
With
pip install 'dash==0.38.0' dash_html_components flask-talisman
you could test quite strict CSP settings in Dash locally with success:With
dash==0.39.0
however this fails due to the new inline scriptdash/dash/dash.py
Line 174 in 0554546
A work-around could be to add hash of the current Dash generated inline script (
sha256-jZlsGVOhUAIcH+4PVs7QuGZkthRMgvT2n0ilH6/zTM0=
) to the server CSP script src headers, however that would be in need of update when the dash renderer string/configuration changes.Not sure if it is feasible/fits the overall framework/plans, but could one suggestion be to follow the same concept as when the user e.g. wants to override the default
favicon.ico
(i.e. a filefavicon.ico
is placed in theassets
folder - here in this case it could be e.g. a filedash-renderer-config.js
). In addition to following the same concept in terms of overriding default assets and continue not having inline scripts in Dash core, it perhaps also better facilitates separation of Python- and JavaScript code.The text was updated successfully, but these errors were encountered: