Skip to content
Permalink
Browse files

Fix static mounts using relative paths and prevent traversal exploits (

…#554)

Thanks, @abdusco! Closes #555
  • Loading branch information...
abdusco authored and simonw committed Jul 11, 2019
1 parent 9ca860e commit 74ecf8a7cc45cabf369e510c7214f5ed85c8c6d8
Showing with 9 additions and 2 deletions.
  1. +2 −1 datasette/utils/__init__.py
  2. +5 −1 datasette/utils/asgi.py
  3. +2 −0 tests/test_html.py
@@ -735,7 +735,8 @@ def convert(self, value, param, ctx):
param,
ctx,
)
path, dirpath = value.split(":")
path, dirpath = value.split(":", 1)
dirpath = os.path.abspath(dirpath)
if not os.path.exists(dirpath) or not os.path.isdir(dirpath):
self.fail("%s is not a valid directory path" % value, param, ctx)
return path, dirpath
@@ -300,7 +300,11 @@ def __init__(self, send):
def asgi_static(root_path, chunk_size=4096, headers=None, content_type=None):
async def inner_static(scope, receive, send):
path = scope["url_route"]["kwargs"]["path"]
full_path = (Path(root_path) / path).absolute()
try:
full_path = (Path(root_path) / path).resolve().absolute()
except FileNotFoundError:
await asgi_send_html(send, "404", 404)
return
# Ensure full_path is within root_path to avoid weird "../" tricks
try:
full_path.relative_to(root_path)
@@ -67,6 +67,8 @@ def test_static_mounts():
assert response.status == 200
response = client.get("/custom-static/not_exists.py")
assert response.status == 404
response = client.get("/custom-static/../LICENSE")
assert response.status == 404


def test_memory_database_page():

0 comments on commit 74ecf8a

Please sign in to comment.
You can’t perform that action at this time.