##// END OF EJS Templates
Merge pull request #7016 from rgbkrk/csp...
Min RK -
r19161:d56bcc10 merge
parent child Browse files
Show More
@@ -0,0 +1,4 b''
1 # URI for the CSP Report. Included here to prevent a cyclic dependency.
2 # csp_report_uri is needed both by the BaseHandler (for setting the report-uri)
3 # and by the CSPReportHandler (which depends on the BaseHandler).
4 csp_report_uri = r"/api/security/csp-report"
@@ -0,0 +1,23 b''
1 """Tornado handlers for security logging."""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 from tornado import gen, web
7
8 from ...base.handlers import IPythonHandler, json_errors
9 from . import csp_report_uri
10
11 class CSPReportHandler(IPythonHandler):
12 '''Accepts a content security policy violation report'''
13 @web.authenticated
14 @json_errors
15 def post(self):
16 '''Log a content security policy violation report'''
17 csp_report = self.get_json_body()
18 self.log.warn("Content security violation: %s",
19 self.request.body.decode('utf8', 'replace'))
20
21 default_handlers = [
22 (csp_report_uri, CSPReportHandler)
23 ]
@@ -32,6 +32,8 b' from IPython.utils.path import filefind'
32 32 from IPython.utils.py3compat import string_types
33 33 from IPython.html.utils import is_hidden, url_path_join, url_escape
34 34
35 from IPython.html.services.security import csp_report_uri
36
35 37 #-----------------------------------------------------------------------------
36 38 # Top-level handlers
37 39 #-----------------------------------------------------------------------------
@@ -45,17 +47,22 b' class AuthenticatedHandler(web.RequestHandler):'
45 47 def set_default_headers(self):
46 48 headers = self.settings.get('headers', {})
47 49
48 if "X-Frame-Options" not in headers:
49 headers["X-Frame-Options"] = "SAMEORIGIN"
50 if "Content-Security-Policy" not in headers:
51 headers["Content-Security-Policy"] = (
52 "frame-ancestors 'self'; "
53 # Make sure the report-uri is relative to the base_url
54 "report-uri " + url_path_join(self.base_url, csp_report_uri) + ";"
55 )
50 56
57 # Allow for overriding headers
51 58 for header_name,value in headers.items() :
52 59 try:
53 60 self.set_header(header_name, value)
54 except Exception:
61 except Exception as e:
55 62 # tornado raise Exception (not a subclass)
56 63 # if method is unsupported (websocket and Access-Control-Allow-Origin
57 64 # for example, so just ignore)
58 pass
65 self.log.debug(e)
59 66
60 67 def clear_login_cookie(self):
61 68 self.clear_cookie(self.cookie_name)
@@ -225,7 +225,7 b' class NotebookWebApplication(web.Application):'
225 225 handlers.extend(load_handlers('services.sessions.handlers'))
226 226 handlers.extend(load_handlers('services.nbconvert.handlers'))
227 227 handlers.extend(load_handlers('services.kernelspecs.handlers'))
228
228 handlers.extend(load_handlers('services.security.handlers'))
229 229 handlers.append(
230 230 (r"/nbextensions/(.*)", FileFindHandler, {
231 231 'path': settings['nbextensions_path'],
@@ -65,7 +65,10 b' class KernelAPITest(NotebookTestBase):'
65 65 self.assertEqual(r.status_code, 201)
66 66 self.assertIsInstance(kern1, dict)
67 67
68 self.assertEqual(r.headers['x-frame-options'], "SAMEORIGIN")
68 self.assertEqual(r.headers['Content-Security-Policy'], (
69 "frame-ancestors 'self'; "
70 "report-uri /api/security/csp-report;"
71 ))
69 72
70 73 def test_main_kernel_handler(self):
71 74 # POST request
@@ -75,7 +78,10 b' class KernelAPITest(NotebookTestBase):'
75 78 self.assertEqual(r.status_code, 201)
76 79 self.assertIsInstance(kern1, dict)
77 80
78 self.assertEqual(r.headers['x-frame-options'], "SAMEORIGIN")
81 self.assertEqual(r.headers['Content-Security-Policy'], (
82 "frame-ancestors 'self'; "
83 "report-uri /api/security/csp-report;"
84 ))
79 85
80 86 # GET request
81 87 r = self.kern_api.list()
@@ -180,16 +180,42 b' Backwards incompatible changes'
180 180
181 181 .. DO NOT EDIT THIS LINE BEFORE RELEASE. INCOMPAT INSERTION POINT.
182 182
183 IFrame embedding
184 ````````````````
183 Content Security Policy
184 ```````````````````````
185 185
186 The IPython Notebook and its APIs by default will only be allowed to be
187 embedded in an iframe on the same origin.
186 The Content Security Policy is a web standard for adding a layer of security to
187 detect and mitigate certain classes of attacks, including Cross Site Scripting
188 (XSS) and data injection attacks. This was introduced into the notebook to
189 ensure that the IPython Notebook and its APIs (by default) can only be embedded
190 in an iframe on the same origin.
188 191
189 To override this, set ``headers[X-Frame-Options]`` to one of
192 Override ``headers['Content-Security-Policy']`` within your notebook
193 configuration to extend for alternate domains and security settings.::
190 194
191 * DENY
192 * SAMEORIGIN
193 * ALLOW-FROM uri
195 c.NotebookApp.tornado_settings = {
196 'headers': {
197 'Content-Security-Policy': "frame-ancestors 'self'"
198 }
199 }
194 200
195 See `Mozilla's guide to X-Frame-Options <https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options>`_ for more examples.
201 Example policies::
202
203 Content-Security-Policy: default-src 'self' https://*.jupyter.org
204
205 Matches embeddings on any subdomain of jupyter.org, so long as they are served
206 over SSL.
207
208 There is a `report-uri <https://developer.mozilla.org/en-US/docs/Web/Security/CSP/CSP_policy_directives#report-uri>`_ endpoint available for logging CSP violations, located at
209 ``/api/security/csp-report``. To use it, set ``report-uri`` as part of the CSP::
210
211 c.NotebookApp.tornado_settings = {
212 'headers': {
213 'Content-Security-Policy': "frame-ancestors 'self'; report-uri /api/security/csp-report"
214 }
215 }
216
217 It simply provides the CSP report as a warning in IPython's logs. The default
218 CSP sets this report-uri relative to the ``base_url`` (not shown above).
219
220 For a more thorough and accurate guide on Content Security Policies, check out
221 `MDN's Using Content Security Policy <https://developer.mozilla.org/en-US/docs/Web/Security/CSP/Using_Content_Security_Policy>`_ for more examples.
General Comments 0
You need to be logged in to leave comments. Login now