superset
superset copied to clipboard
Cannot send Cross-Origin-Resource-Policy from embed code
Bug description
I cannot force the embedded chart to sent the Cross-Origin-Resource-Policy
header. I have set the CORS options and embedding parameters for iframe embedding as well as Cookie and CSP policy.
Superset is hosted at localhost:8088
while I'm embedding charts at localhost:9000
.
I have followed the configuraiton of Flask CORS_OPTIONS
here, but I cannot get rid of sending the right headers from the embedded chart.
This is my superset_config.py
# CORS OPTIONS
ENABLE_CORS = True
CORS_OPTIONS = {
'supports_credentials': True,
'allow_headers': ['*'],
'resources':['*'],
'origins': [ 'http://localhost:9000', 'http://localhost:8088']
}
SUPERSET_FEATURE_EMBEDDED_SUPERSET=True
# EMBED CODE IFRAME OPTIONS
OVERRIDE_HTTP_HEADERS = {'X-Frame-Options': 'ALLOWALL'}
HTTP_HEADERS = {"X-Frame-Options":"ALLOWALL"}
SUPERSET_WEBSERVER_DOMAINS = [ 'localhost', 'localhost:8088', 'localhost:9000']
# SESSION_COOKIE_DOMAIN
# (default: "Lax") Prevents the browser from sending this cookie along with cross-site requests.
SESSION_COOKIE_SAMESITE = "None"
# (default: False): Controls if cookies should be set with the HttpOnly flag.
SESSION_COOKIE_HTTPONLY = False
# (default: False) Browsers will only send cookies with requests over HTTPS if the cookie is marked “secure”.
# The application must be served over HTTPS for this to make sense.
SESSION_COOKIE_SECURE = False
#CSRF_COOKIE_HTTPONLY = False
WTF_CSRF_ENABLED = False
# TALISMAN_ENABLED defaults to True; set this to False in order to disable CSP
# @see https://superset.apache.org/docs/security/#csp-requirements
TALISMAN_ENABLED = False
# you grant public role the same set of permissions as for the GAMMA role.
# This is useful if one wants to enable anonymous users to view dashboards.
# @see https://apache-superset.readthedocs.io/en/0.35.1/security.html
PUBLIC_ROLE_LIKE_GAMMA = False
# For environments where CSP policies are defined outside of Superset using other software, administrators can disable this warning
CONTENT_SECURITY_POLICY_WARNING = False
and the iframe was
<iframe
width="600"
height="400"
seamless
frameBorder="0"
allowfullscreen
scrolling="no"
src="http://localhost:8088/superset/explore/p/a8yN1wGMobp/?standalone=1&height=400&show_filters=true&expand_filters=true"
>
</iframe>
while the python server serving that iframe is
#!/usr/bin/env python3
from http.server import HTTPServer, SimpleHTTPRequestHandler, test
import sys
class CORSRequestHandler (SimpleHTTPRequestHandler):
def end_headers (self):
"""
Cross-Origin-Resource-Policy: cross-origin if the resource is served from another location than your website. ⚠️If you set this header, any website can embed this resource.
Cross-Origin-Resource-Policy: same-site if the resource and your site are served from the same site.
Cross-Origin-Embedder-Policy: credentialless instead of require-corp. It allows loading the resource, despite the missing CORP header, at the cost of requesting it without credentials like Cookies.
"""
self.send_header('Cross-Origin-Embedder-Policy', 'credentialless') #require-corp
self.send_header('Cross-Origin-Opener-Policy', 'cross-origin') #same-origin
self.send_header('Cross-Origin-Resource-Policy', ' cross-origin')
self.send_header('X-Frame-Options', 'allow-from *')
self.send_header("Access-Control-Allow-Origin", "*")
SimpleHTTPRequestHandler.end_headers(self)
test(CORSRequestHandler, HTTPServer, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)
How to reproduce the bug
- Copy the
superset_config.py
provided above - Copy the
html
code above in aembed.html
page - Create a
cors.py
python code - execute
python cors.py 9000
to serve the embedded chart
Screenshots/recordings
The Chrome error was
Specify a Cross-Origin Resource Policy to prevent a resource from being blocked
Because your site has the Cross-Origin Embedder Policy (COEP) enabled, each resource must specify a suitable Cross-Origin Resource Policy (CORP). This behavior prevents a document from loading cross-origin resources which don’t explicitly grant permission to be loaded.
To solve this, add the following to the resource’ response header:
Cross-Origin-Resource-Policy: same-site if the resource and your site are served from the same site.
Cross-Origin-Resource-Policy: cross-origin if the resource is served from another location than your website. ⚠️If you set this header, any website can embed this resource.
Alternatively, the document can use the variant: Cross-Origin-Embedder-Policy: credentialless instead of require-corp. It allows loading the resource, despite the missing CORP header, at the cost of requesting it without credentials like Cookies.
Superset version
master / latest-dev
Python version
3.9
Node version
18 or greater
Browser
Chrome
Additional context
No response
Checklist
- [X] I have searched Superset docs and Slack and didn't find a solution to my problem.
- [X] I have searched the GitHub issue tracker and didn't find a similar bug report.
- [X] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.
[NOTE]
Using
OVERRIDE_HTTP_HEADERS = { 'X-Frame-Options': 'ALLOWALL' }
HTTP_HEADERS = { "X-Frame-Options" : "ALLOWALL" }
or as detailed here
HTTP_HEADERS = {}
does not solve this issue.
My solution was to write a Flask Middlware to send the proper headers, specifically
response.headers.add("Cross-Origin-Embedder-Policy", 'require-corp')
response.headers.add("Cross-Origin-Resource-Policy", 'cross-origin')
As alternative, when using a reverse proxy (e.g. nginix) it is possible to add to the nginix/nginix.conf
add_header Cross-Origin-Resource-Policy "cross-origin";
Of course the Flask middleware solution is more flexible for development purposes.
This will only work if you disable Talisman and set your own Content Security Policy in the superset_config.py #Disables the CSP **TALISMAN_ENABLED = False
#Allows any website to embed the iframe on its website #OVERRIDE_HTTP_HEADERS = { "X-Frame-Options": "ALLOWALL" }
#Allows only your website to be the only website allowed to embed dashboards OVERRIDE_HTTP_HEADERS = { "Content-Security-Policy": "frame-ancestors http://your.domain.com;" }
ALLOW-FROM http://your.domain.com is deprecated and no longer works on modern browsers.