Package: release.debian.org Severity: normal Tags: jessie User: [email protected] Usertags: pu
Hi, there has been a directory traversal bug in servefile, it was fixed in version 0.4.4. I talked to the Debian security team and they said a DSA would not be necessary and recommended doing a stable-pu. Therefore I'd like to propose an update to 0.4.4 (debdiff attached). Greetings, seba -- System Information: Debian Release: stretch/sid APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.1.0-1-amd64 (SMP w/4 CPU cores) Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system)
diff -Nru servefile-0.4.3/ChangeLog servefile-0.4.4/ChangeLog --- servefile-0.4.3/ChangeLog 2013-12-28 01:55:41.000000000 +0100 +++ servefile-0.4.4/ChangeLog 2015-11-10 21:05:35.000000000 +0100 @@ -1,6 +1,18 @@ servefile changelog =================== +2015-11-10 v0.4.4 +----------------- + + 0.4.4 released + + * prefer using TLS1.2/TLS1 with --ssl if available + * issue v3 certificates for self signed certificates with --ssl + * removed lots of unnecessary error output + * fixed a bug where wrong ranges were used on a HEAD request in directory listing mode + * fixed a bug where directory listing mode allowed path traversal + + 2013-12-28 v0.4.3 ----------------- diff -Nru servefile-0.4.3/debian/changelog servefile-0.4.4/debian/changelog --- servefile-0.4.3/debian/changelog 2014-08-12 22:11:04.000000000 +0200 +++ servefile-0.4.4/debian/changelog 2015-11-11 15:52:59.000000000 +0100 @@ -1,3 +1,9 @@ +servefile (0.4.4-1~deb8u1) jessie; urgency=high + + * New upstream version + + -- Sebastian Lohff <[email protected]> Tue, 10 Nov 2015 21:22:17 +0100 + servefile (0.4.3-1) unstable; urgency=low * New upstream version diff -Nru servefile-0.4.3/debian/control servefile-0.4.4/debian/control --- servefile-0.4.3/debian/control 2014-08-13 00:41:01.000000000 +0200 +++ servefile-0.4.4/debian/control 2015-11-10 21:27:07.000000000 +0100 @@ -3,7 +3,7 @@ Priority: optional Maintainer: Sebastian Lohff <[email protected]> Build-Depends: debhelper (>= 9.0~), python -Standards-Version: 3.9.5 +Standards-Version: 3.9.6 Homepage: http://seba-geek.de/stuff/servefile/ Package: servefile diff -Nru servefile-0.4.3/PKG-INFO servefile-0.4.4/PKG-INFO --- servefile-0.4.3/PKG-INFO 2013-12-28 02:31:38.000000000 +0100 +++ servefile-0.4.4/PKG-INFO 2015-11-10 21:13:09.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: servefile -Version: 0.4.3 +Version: 0.4.4 Summary: Serve files from shell via a small HTTP server Home-page: http://seba-geek.de/stuff/servefile/ Author: Sebastian Lohff diff -Nru servefile-0.4.3/servefile servefile-0.4.4/servefile --- servefile-0.4.3/servefile 2013-12-28 02:21:57.000000000 +0100 +++ servefile-0.4.4/servefile 2015-11-10 20:54:36.000000000 +0100 @@ -7,7 +7,7 @@ from __future__ import print_function -__version__ = '0.4.3' +__version__ = '0.4.4' import argparse import base64 @@ -16,7 +16,6 @@ import mimetypes import urllib import os -import posixpath import re import select import socket @@ -102,7 +101,7 @@ try: fromto[0] = int(fromto[0]) fromto[1] = int(fromto[1]) - except: + except ValueError: return (False, None) if fromto[0] >= fileLength or fromto[0] < 0 or fromto[1] >= fileLength or fromto[1]-fromto[0] < 0: @@ -154,11 +153,7 @@ self.end_headers() block = self.getChunk(myfile, fromto) while block: - try: - self.wfile.write(block) - except socket.error as e: - print("%s ABORTED transmission (Reason %s: %s)" % (self.client_address[0], e[0], e[1])) - return False + self.wfile.write(block) block = self.getChunk(myfile, fromto) myfile.close() print("%s finished downloading %s" % (self.client_address[0], filePath)) @@ -310,6 +305,15 @@ """ Send file or directory index, depending on requested path """ path = self.getCleanPath() + # check if path is in current serving directory + currBaseDir = os.path.abspath(self.targetDir) + os.path.sep + requestPath = os.path.normpath(os.path.join(currBaseDir, path)) + os.path.sep + if not requestPath.startswith(currBaseDir): + self.send_response(301) + self.send_header("Location", '/') + self.end_headers() + return + if os.path.isdir(path): if not self.path.endswith('/'): self.send_response(301) @@ -325,7 +329,7 @@ self.end_headers() else: self.send_response(200) - self.sendContentHeaders(self, path, length) + self.sendContentHeaders(path, length) self.end_headers() else: self.sendFile(path, head) @@ -406,7 +410,7 @@ </tr> </thead> <tbody> - """ % {'path': posixpath.normpath(urllib.unquote(self.path))} + """ % {'path': os.path.normpath(urllib.unquote(self.path))} footer = """</tbody></table></div> <div class="footer"><a href="http://seba-geek.de/stuff/servefile/">servefile %(version)s</a></div> </body> @@ -468,7 +472,7 @@ return (size, ext.strip()) def getCleanPath(self): - urlPath = posixpath.normpath(urllib.unquote(self.path)).strip("/") + urlPath = os.path.normpath(urllib.unquote(self.path)).strip("/") path = os.path.join(self.targetDir, urlPath) return path @@ -626,7 +630,9 @@ # never reached class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer): - pass + def handle_error(self, request, client_address): + print("%s ABORTED transmission (Reason: %s)" % (client_address[0], sys.exc_value)) + def catchSSLErrors(BaseSSLClass): """ Class decorator which catches SSL errors and prints them. """ @@ -645,7 +651,19 @@ class SecureThreadedHTTPServer(ThreadedHTTPServer): def __init__(self, pubKey, privKey, server_address, RequestHandlerClass, bind_and_activate=True): ThreadedHTTPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate) - ctx = SSL.Context(SSL.SSLv23_METHOD) + + # choose TLS1.2 or TLS1, if available + sslMethod = None + if hasattr(SSL, "TLSv1_2_METHOD"): + sslMethod = SSL.TLSv1_2_METHOD + elif hasattr(SSL, "TLSv1_METHOD"): + sslMethod = SSL.TLSv1_METHOD + else: + # only SSLv23 available + print("Warning: Only SSLv2/SSLv3 is available, connection might be insecure.") + sslMethod = SSL.SSLv23_METHOD + + ctx = SSL.Context(sslMethod) if type(pubKey) is crypto.X509 and type(privKey) is crypto.PKey: ctx.use_certificate(pubKey) ctx.use_privatekey(privKey) @@ -661,7 +679,11 @@ self.server_activate() def shutdown_request(self, request): - request.shutdown() + try: + request.shutdown() + except SSL.Error: + # ignore SSL errors on connection shutdown + pass class SecureHandler(): @@ -782,6 +804,8 @@ req.sign(pkey, "sha1") cert = crypto.X509() + # Mozilla only accepts v3 certificates with v3 extensions, not v1 + cert.set_version(0x2) # some browsers complain if they see a cert from the same authority # with the same serial ==> we just use the seconds as serial. cert.set_serial_number(int(time.time())) diff -Nru servefile-0.4.3/servefile.1 servefile-0.4.4/servefile.1 --- servefile-0.4.3/servefile.1 2013-12-28 02:30:48.000000000 +0100 +++ servefile-0.4.4/servefile.1 2015-11-10 21:12:39.000000000 +0100 @@ -1,4 +1,4 @@ -.TH SERVEFILE 1 "December 2013" "servefile 0.4.3" "User Commands" +.TH SERVEFILE 1 "November 2015" "servefile 0.4.4" "User Commands" .SH NAME servefile \- small HTTP-Server for temporary file transfer diff -Nru servefile-0.4.3/setup.py servefile-0.4.4/setup.py --- servefile-0.4.3/setup.py 2013-12-28 02:22:22.000000000 +0100 +++ servefile-0.4.4/setup.py 2015-11-10 21:11:58.000000000 +0100 @@ -7,7 +7,7 @@ description='Serve files from shell via a small HTTP server', long_description='Serve files from shell via a small HTTP server. The server redirects all HTTP requests to the file, so only IP and port must be given to another user to access the file. Its main purpose is to quickly send a file to users in your local network, independent of their current setup (OS/software). Beneath that it also supports uploads, SSL, HTTP basic auth and directory listings.', platforms='posix', - version='0.4.3', + version='0.4.4', license='GPLv3 or later', url='http://seba-geek.de/stuff/servefile/', author='Sebastian Lohff',

