Vulnerability: Moderate severity vulnerability that affects notebook Jupyter Notebook before 5.7.1 allows XSS via an untrusted notebook because nbconvert responses are considered to have the same origin as the notebook server. In other words, nbconvert endpoints can execute JavaScript with access to the server API. In notebook/nbconvert/handlers.py, NbconvertFileHandler and NbconvertPostHandler do not set a Content Security Policy to prevent this.
Vulnerability ID: GHSA-49qr-xh3w-h436
CWE: CWE-79
Severity score: 6.1
Project: https://github.com/jupyter/notebook
Published: 2018-11-21
File: notebook/nbconvert/handlers.py
Commit message: Apply CSP sandboxing for nbconvert responses

These may contain untrusted content, so they should be treated as being
from a different domain to the notebook server.
Commit author: Thomas Kluyver

Vulnerable version (before fix):
 class NbconvertFileHandler(IPythonHandler):      SUPPORTED_METHODS = ('GET',)      @web.authenticated     def get(self, format, path):  def get(self, format, path): class NbconvertPostHandler(IPythonHandler):     SUPPORTED_METHODS = ('POST',)      @web.authenticated     def post(self, format):         exporter = get_exporter(format, config=self.config)

Fixed version (after fix):
 class NbconvertFileHandler(IPythonHandler):      SUPPORTED_METHODS = ('GET',)      @property     def content_security_policy(self):         # In case we're serving HTML/SVG, confine any Javascript to a unique         # origin so it can't interact with the notebook server.         return super(NbconvertFileHandler, self).content_security_policy + \                "; sandbox allow-scripts"      @web.authenticated     def get(self, format, path):  def get(self, format, path): class NbconvertPostHandler(IPythonHandler):     SUPPORTED_METHODS = ('POST',)      @property     def content_security_policy(self):         # In case we're serving HTML/SVG, confine any Javascript to a unique         # origin so it can't interact with the notebook server.         return super(NbconvertPostHandler, self).content_security_policy + \                "; sandbox allow-scripts"      @web.authenticated     def post(self, format):         exporter = get_exporter(format, config=self.config)

Patch:
patch: @@ -78,6 +78,13 @@ class NbconvertFileHandler(IPythonHandler):
 
     SUPPORTED_METHODS = ('GET',)
 
+    @property
+    def content_security_policy(self):
+        # In case we're serving HTML/SVG, confine any Javascript to a unique
+        # origin so it can't interact with the notebook server.
+        return super(NbconvertFileHandler, self).content_security_policy + \
+               "; sandbox allow-scripts"
+
     @web.authenticated
     def get(self, format, path):
 
@@ -145,6 +152,13 @@ def get(self, format, path):
 class NbconvertPostHandler(IPythonHandler):
     SUPPORTED_METHODS = ('POST',)
 
+    @property
+    def content_security_policy(self):
+        # In case we're serving HTML/SVG, confine any Javascript to a unique
+        # origin so it can't interact with the notebook server.
+        return super(NbconvertPostHandler, self).content_security_policy + \
+               "; sandbox allow-scripts"
+
     @web.authenticated
     def post(self, format):
         exporter = get_exporter(format, config=self.config)
path: notebook/nbconvert/handlers.py