From 5fea2d92949b00e7ee87a9d21fa64c7a0d6d2f96 Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Tue, 5 May 2015 09:40:31 +0200 Subject: [PATCH] Security fix --- butterfly.server.py | 29 ++++++++++++++++++++++++----- butterfly/static/main.js | 11 +++++++++-- coffees/term.coffee | 10 +++++++++- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/butterfly.server.py b/butterfly.server.py index beee978..19e5fd0 100755 --- a/butterfly.server.py +++ b/butterfly.server.py @@ -21,6 +21,7 @@ import tornado.options import tornado.ioloop import tornado.httpserver import tornado_systemd +import logging import uuid import ssl import getpass @@ -29,7 +30,6 @@ import stat import socket import sys - tornado.options.define("debug", default=False, help="Debug mode") tornado.options.define("more", default=False, help="Debug mode with more verbosity") @@ -54,15 +54,18 @@ tornado.options.define("ssl_version", default=None, help="SSL protocol version") tornado.options.define("generate_certs", default=False, help="Generate butterfly certificates") +tornado.options.define("generate_current_user_pkcs", default=False, + help="Generate current user pfx for client " + "authentication") tornado.options.define("generate_user_pkcs", default='', - help="Generate user pfx for client authentication") + help="Generate user pfx for client authentication " + "(Must be root to create for another user)") tornado.options.define("unminified", default=False, help="Use the unminified js (for development only)") tornado.options.parse_command_line() -import logging for logger in ('tornado.access', 'tornado.application', 'tornado.general', 'butterfly'): level = logging.WARNING @@ -164,13 +167,29 @@ if tornado.options.options.generate_certs: sys.exit(0) -if tornado.options.options.generate_user_pkcs: +if (tornado.options.options.generate_current_user_pkcs or + tornado.options.options.generate_user_pkcs): + from butterfly import utils + try: + current_user = utils.User() + except Exception: + current_user = None + from OpenSSL import crypto if not all(map(os.path.exists, [ca, ca_key])): print('Please generate certificates using --generate-certs before') sys.exit(1) - user = tornado.options.options.generate_user_pkcs + if tornado.options.options.generate_current_user_pkcs: + user = current_user.name + else: + user = tornado.options.options.generate_user_pkcs + + if user != current_user.name and current_user.uid != 0: + print('Cannot create certificate for another user with ' + 'current privileges.') + sys.exit(1) + ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, read(ca)) ca_pk = crypto.load_privatekey(crypto.FILETYPE_PEM, read(ca_key)) diff --git a/butterfly/static/main.js b/butterfly/static/main.js index 333c380..2ed1dca 100644 --- a/butterfly/static/main.js +++ b/butterfly/static/main.js @@ -750,7 +750,7 @@ }; Terminal.prototype.write = function(data) { - var attr, b64, c, ch, content, cs, i, k, l, len, line, m, mime, num, pt, ref, ref1, ref2, ref3, ref4, type, valid; + var attr, b64, c, ch, content, cs, i, k, l, len, line, m, mime, num, pt, ref, ref1, ref2, ref3, type, valid; i = 0; l = data.length; while (i < l) { @@ -1196,7 +1196,14 @@ this.screen[this.y + this.shift][1] = true; break; case "IMAGE": - ref4 = content.split(';', 2), mime = ref4[0], b64 = ref4[1]; + content = encodeURI(content); + if (content.indexOf(';')) { + mime = content.slice(0, content.indexOf(';')); + b64 = content.slice(content.indexOf(';') + 1); + } else { + mime = 'image'; + b64 = content; + } attr = this.cloneAttr(this.curAttr); attr.html = ""; this.screen[this.y + this.shift][0][this.x] = attr; diff --git a/coffees/term.coffee b/coffees/term.coffee index 70e3515..d767cf7 100644 --- a/coffees/term.coffee +++ b/coffees/term.coffee @@ -1095,7 +1095,15 @@ class Terminal @screen[@y + @shift][1] = true when "IMAGE" - [mime, b64] = content.split(';', 2) + # Prevent injection + content = encodeURI content + + if content.indexOf(';') + mime = content.slice(0, content.indexOf(';')) + b64 = content.slice(content.indexOf(';') + 1) + else + mime = 'image' + b64 = content attr = @cloneAttr @curAttr attr.html = ( "