Use CSP header to treat served files as belonging to a separate origin#3341
Conversation
|
|
||
| # In case we're serving HTML/SVG, confine any Javascript to a unique | ||
| # origin so it can't interact with the notebook server. | ||
| self.set_header('Content-Security-Policy', 'sandbox allow-scripts') |
There was a problem hiding this comment.
This also overrides any currently set Content-Security-Policy -- should we merge with the operator's settings?
Note: I refer to operator to mean whoever administers this deployment, whether a local server user or a jupyterhub administrator.
There was a problem hiding this comment.
Yes, good point. Do you think it's sufficient to use add_header() to do this, or should we get into checking any existing Content-Security-Policy headers?
There was a problem hiding this comment.
Can multiple CSP headers be set and do what we want? If not, we might want to override the inherited content_security_policy property instead.
There was a problem hiding this comment.
You can use the Content-Security-Policy header more than once... Adding additional policies can only further restrict the capabilities of the protected resource
I think that means this should work, but maybe the c_s_p property is a neater way to achieve the same thing?
There was a problem hiding this comment.
Interesting, I didn't realize we could add multiple headers with the same key. How does set_header work when there are multiple headers with the same key from add_header?
There was a problem hiding this comment.
I think set_header blows away anything that was set before.
There was a problem hiding this comment.
My question comes down to "what's the set of headers after running the following"
self.add_header("X", "y")
self.add_header("X", "z")
self.set_header("X", "x")There was a problem hiding this comment.
AIUI, only X: x would remain.
There was a problem hiding this comment.
I'm thinking using only one header is good. For now I think the value you've set here is a very sane default and further enhancements on merging content security policies can be separate work.
|
OK, I've redone this to achieve the same thing by overriding the |
|
I just re-kicked the appveyor build and somehow it went faster than I expected. At any rate, I certainly approve again. 😄 |
We already contain these files using the
/view/handler, which displays them inside an iframe with the same sandboxing. This PR ensures that if a user ends up viewing an untrusted HTML/SVG file at a/files/URL (instead of/view/), it will still be sandboxed, using the Content-Security Policy: sandbox header.The browser then treats the page as having a unique origin, so cross-origin protection prevents any Javascript from communicating with the notebook server.