Skip to content

Commit 8abc6df

Browse files
committed
enable tornado xsrf cookie
1 parent 18596de commit 8abc6df

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

notebook/base/handlers.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,12 @@ def check_origin(self, origin_to_satisfy_tornado=""):
285285
host = self.request.headers.get("Host")
286286
origin = self.request.headers.get("Origin")
287287

288-
# If no header is provided, assume it comes from a script/curl.
289-
# We are only concerned with cross-site browser stuff here.
288+
# If no header is provided, allow it.
289+
# Origin can be None for:
290+
# - same-origin (IE, Firefox)
291+
# - Cross-site POST form (IE, Firefox)
292+
# - Scripts
293+
# The cross-site POST (XSRF) case is handled by tornado's xsrf_token
290294
if origin is None or host is None:
291295
return True
292296

@@ -338,6 +342,7 @@ def template_namespace(self):
338342
contents_js_source=self.contents_js_source,
339343
version_hash=self.version_hash,
340344
ignore_minified_js=self.ignore_minified_js,
345+
xsrf_form_html=self.xsrf_form_html,
341346
**self.jinja_template_vars
342347
)
343348

@@ -401,6 +406,15 @@ def prepare(self):
401406
raise web.HTTPError(404)
402407
return super(APIHandler, self).prepare()
403408

409+
def check_xsrf_cookie(self):
410+
"""Check non-empty body on POST for XSRF
411+
412+
instead of checking the cookie for forms.
413+
"""
414+
if self.request.method.upper() == 'POST' and not self.request.body:
415+
# Require non-empty POST body for XSRF
416+
raise web.HTTPError(400, "POST requests must have a JSON body. If no content is needed, use '{}'.")
417+
404418
@property
405419
def content_security_policy(self):
406420
csp = '; '.join([

notebook/notebookapp.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ def init_settings(self, ipython_app, kernel_manager, contents_manager,
192192
login_handler_class=ipython_app.login_handler_class,
193193
logout_handler_class=ipython_app.logout_handler_class,
194194
password=ipython_app.password,
195+
xsrf_cookies=True,
195196

196197
# managers
197198
kernel_manager=kernel_manager,

notebook/templates/login.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<div class="center-nav">
2323
<p class="navbar-text nav">Password{% if token_available %} or token{% endif %}:</p>
2424
<form action="{{base_url}}login?next={{next}}" method="post" class="navbar-form pull-left">
25+
{{ xsrf_form_html() | safe }}
2526
<input type="password" name="password" id="password_input" class="form-control">
2627
<button type="submit" id="login_submit">Log in</button>
2728
</form>

0 commit comments

Comments
 (0)