From a08905e35197e2fa9b5e9c0b2187c6d3754cce63 Mon Sep 17 00:00:00 2001 From: Miguel Barão Date: Tue, 6 Nov 2018 17:15:14 +0000 Subject: [PATCH] - improved security against cross-site request forgery (XRSF). --- serve.py | 4 ++-- static/js/admin.js | 53 +++++++++++++++++++++++++---------------------------- templates/admin.html | 3 +-- templates/test.html | 2 ++ 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/serve.py b/serve.py index fd160ac..61da615 100755 --- a/serve.py +++ b/serve.py @@ -39,7 +39,7 @@ class WebApplication(tornado.web.Application): 'template_path': path.join(path.dirname(__file__), 'templates'), 'static_path': path.join(path.dirname(__file__), 'static'), 'static_url_prefix': '/static/', - 'xsrf_cookies': False, # FIXME not needed on private network + 'xsrf_cookies': True, 'cookie_secret': base64.b64encode(uuid.uuid4().bytes), 'login_url': '/login', 'debug': debug, @@ -105,7 +105,7 @@ class LogoutHandler(BaseHandler): # Based on https://bhch.github.io/posts/2017/12/serving-large-files-with-tornado-safely-without-blocking/ # ---------------------------------------------------------------------------- class FileHandler(BaseHandler): - chunk_size = 1024 * 1024 # serve up to 1 MiB multiple times + chunk_size = 512 * 1024 # serve up to 512 KiB multiple times @tornado.web.authenticated async def get(self): diff --git a/static/js/admin.js b/static/js/admin.js index cda2ffa..6c2b27a 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -1,3 +1,16 @@ +// from: https://www.tornadoweb.org/en/stable/guide/security.html +// with changes: removed datatype and callback from original postJSON +function getCookie(name) { + var r = document.cookie.match("\\b" + name + "=([^;]*)\\b"); + return r ? r[1] : undefined; +} + +jQuery.postJSON = function(url, args) { + args._xsrf = getCookie("_xsrf"); + $.ajax({url: url, data: $.param(args), type: "POST"}); +}; + +// --------------------------------------------------------------------------- $(document).ready(function() { function button_handlers() { // button handlers (runs once) @@ -13,28 +26,20 @@ $(document).ready(function() { ); $("#reset_password").click( function () { - $.ajax({ - type: "POST", - url: "/admin", - data: { - "cmd": "reset_password", - "value": $("#reset_number").val() - } + $.postJSON("/admin", { + "cmd": "reset_password", + "value": $("#reset_number").val() }); } ); $("#inserir_novo_aluno").click( function () { - $.ajax({ - type: "POST", - url: "/admin", - data: { - "cmd": "insert_student", - "value": JSON.stringify({ - "number": $("#novo_numero").val(), - "name": $("#novo_nome").val() - }) - } + $.postJSON("/admin", { + "cmd": "insert_student", + "value": JSON.stringify({ + "number": $("#novo_numero").val(), + "name": $("#novo_nome").val() + }) }); } ); @@ -46,20 +51,12 @@ $(document).ready(function() { // checkbox handler to allow/deny students individually function autorizeStudent(e) { if (this.checked) { - $(this).parent().parent().addClass("table-primary"); // row class - $.ajax({ - type: "POST", - url: "/admin", - data: {"cmd": "allow", "value": this.name} - }); + // $(this).parent().parent().addClass("table-primary"); // row class + $.postJSON("/admin", {"cmd": "allow", "value": this.name}); } else { // $(this).parent().parent().removeClass("active"); - $.ajax({ - type: "POST", - url: "/admin", - data: {"cmd": "deny", "value": this.name} - }); + $.postJSON("/admin", {"cmd": "deny", "value": this.name}); } } diff --git a/templates/admin.html b/templates/admin.html index 495bddf..0af4f12 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -24,7 +24,7 @@ - + @@ -140,7 +140,6 @@
-
diff --git a/templates/test.html b/templates/test.html index 4374f29..885dedd 100644 --- a/templates/test.html +++ b/templates/test.html @@ -92,6 +92,8 @@
+ {% module xsrf_form_html() %} + {% for i, q in enumerate(t['questions']) %} {% module Template(templ[q['type']], i=i, q=q, md=md(q['ref']), show_ref=t['show_ref']) %} {% end %} -- libgit2 0.21.2