flask-restx
flask-restx copied to clipboard
Inline CSS style breaks Swagger UI due to content security policy (Flask Talisman)
Flask Talisman is often used to secure a flask application.
If Flask Talisman is added to a Flask Restx project, the Swagger UI is no longer rendered in any modern browser. Adding Flask Talisman is done with:
from flask import Flask
from flask_talisman import Talisman
app = Flask()
...
Talisman(app)
Browser says: Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-xmHxD8PCyVLff5pky6+I50yPBEE+4wkuKmblJOCd+Wo='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
Reason is the inline CSS in https://github.com/python-restx/flask-restx/blob/84ae8361526005b8f1cf147b428d00c1faa86491/flask_restx/templates/swagger-ui-css.html#L14
The easiest solution would be to move this inline CSS to an extra file. Generating a nonce or hash seems to be too complicated as it needs to be done on every page request. Also, it would require a direct integration between Flask Restx and Talisman.
A workaround is allowing such inline CSS, but this basically makes using a content security policy pointless.
Talisman(app, content_security_policy={
'style-src': [
'\'unsafe-inline\'',
'\'self\'',
]
})
Environment
- Python version: 3.8.6
- Flask version: 1.1.2
- Flask-RESTX version: 0.2.0
- flask-talisman: 0.7.0
Hello, just bumped into this very same bug. Any clue how to fix it please?
Same here, but with usual Flask-talisman and Connexion. Workaround does not work... https://stackoverflow.com/questions/58610678/flask-talisman-breaks-flask-restplus-swagger-documentation https://github.com/HolimaX/libgopyu/issues/31
This might work for anyone, Now looking for the solution of using inline styling with their flask talisman webapp. The python flask server:
talisman = Talisman(app, content_security_policy={ 'default-src': '\'self\' \'unsafe-inline\'', 'script-src': [ '\'self\'', 'https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js', 'https://code.jquery.com/jquery-3.6.1.js', 'https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.2/socket.io.min.js', 'https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@700&display=swap', 'https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@200&display=swap', 'https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@100&display=swap', 'https://media.giphy.com/media/nrXif9YExO9EI/giphy.gif?cid=790b76118trl1i3udzuxz9ooii2delftggwniyxrkmjawsky&ep=v1_gifs_search&rid=giphy.gif&ct=g', '\'unsafe-inline\'' ], })
Keep in mind the following url styling will not work!
background-image: url('https://media.giphy.com/media/nrXif9YExO9EI/giphy.gif?cid=790b76118trl1i3udzuxz9ooii2delftggwniyxrkmjawsky&ep=v1_gifs_search&rid=giphy.gif&ct=g');