forbid serving hidden files from `/files`

MinRK 12 years ago
parent a45e997176
commit 2fcc7fe97f

@ -43,6 +43,10 @@ from IPython.external.decorator import decorator
from IPython.utils.path import filefind
from IPython.utils.jsonutil import date_default
# UF_HIDDEN is a stat flag not defined in the stat module.
# It is used by BSD to indicate hidden files.
UF_HIDDEN = getattr(stat, 'UF_HIDDEN', 32768)
#-----------------------------------------------------------------------------
# Monkeypatch for Tornado <= 2.1.1 - Remove when no longer necessary!
#-----------------------------------------------------------------------------
@ -263,6 +267,7 @@ class IPythonHandler(AuthenticatedHandler):
raise web.HTTPError(400, u'Invalid JSON in body of request')
return model
class AuthenticatedFileHandler(IPythonHandler, web.StaticFileHandler):
"""static files should only be accessible when logged in"""
@ -272,7 +277,39 @@ class AuthenticatedFileHandler(IPythonHandler, web.StaticFileHandler):
name = os.path.basename(path)
self.set_header('Content-Type', 'application/json')
self.set_header('Content-Disposition','attachment; filename="%s"' % name)
return web.StaticFileHandler.get(self, path)
def validate_absolute_path(self, root, absolute_path):
"""Validate and return the absolute path.
Requires tornado 3.1
Adding to tornado's own handling, forbids the serving of hidden files.
"""
abs_path = super(AuthenticatedFileHandler, self).validate_absolute_path(root, absolute_path)
abs_root = os.path.abspath(root)
self.forbid_hidden(abs_root, abs_path)
return abs_path
def forbid_hidden(self, absolute_root, absolute_path):
"""Raise 403 if a file is hidden or contained in a hidden directory.
Hidden is determined by either name starting with '.'
or the UF_HIDDEN flag as reported by stat
"""
inside_root = absolute_path[len(absolute_root):]
if any(part.startswith('.') for part in inside_root.split(os.path.sep)):
raise web.HTTPError(403)
# check UF_HIDDEN on any location up to root
path = absolute_path
while path and path.startswith(absolute_root):
if os.stat(path).st_flags & UF_HIDDEN:
raise web.HTTPError(403)
path, _ = os.path.split(path)
return absolute_path
def json_errors(method):

Loading…
Cancel
Save