Prevent directory traversal

This commit is contained in:
grossmj committed 2021-05-15 17:35:32 +09:30
1 parent 2c938b2c19
commit 6294ad9e76
9 files changed
+70 -67

No files matched your search

@@ -409,20 +409,19 @@ class NodeHandler:
path = request.match_info["path"]
path = force_unix_path(path)
# Raise error if user try to escape
if path[0] == ".":
if path[0] == "." or "/../" in path:
raise aiohttp.web.HTTPForbidden()
node_type = node.node_type
path = "/project-files/{}/{}/{}".format(node_type, node.id, path)
res = await node.compute.http_query("GET", "/projects/{project_id}/files{path}".format(project_id=project.id, path=path), timeout=None, raw=True)
response.set_status(200)
response.content_type = "application/octet-stream"
response.enable_chunked_encoding()
await response.prepare(request)
await response.write(res.body)
response.set_status(res.status)
if res.status == 200:
response.content_type = "application/octet-stream"
response.enable_chunked_encoding()
await response.prepare(request)
await response.write(res.body)
# await response.write_eof() #FIXME: shound't be needed anymore
@Route.post(
@@ -446,14 +445,14 @@ class NodeHandler:
path = force_unix_path(path)
# Raise error if user try to escape
if path[0] == ".":
if path[0] == "." or "/../" in path:
raise aiohttp.web.HTTPForbidden()
node_type = node.node_type
path = "/project-files/{}/{}/{}".format(node_type, node.id, path)
data = await request.content.read() #FIXME: are we handling timeout or large files correctly?
await node.compute.http_query("POST", "/projects/{project_id}/files{path}".format(project_id=project.id, path=path), data=data, timeout=None, raw=True)
response.set_status(201)
res = await node.compute.http_query("POST", "/projects/{project_id}/files{path}".format(project_id=project.id, path=path), data=data, timeout=None, raw=True)
response.set_status(res.status)
@Route.get(
r"/projects/{project_id}/nodes/{node_id}/console/ws",
@@ -28,6 +28,7 @@ from gns3server.controller import Controller
from gns3server.controller.import_project import import_project
from gns3server.controller.export_project import export_project
from gns3server.utils.asyncio import aiozipstream
from gns3server.utils.path import is_safe_path
from gns3server.config import Config
@@ -454,14 +455,12 @@ class ProjectHandler:
controller = Controller.instance()
project = await controller.get_loaded_project(request.match_info["project_id"])
path = request.match_info["path"]
path = os.path.normpath(path).strip('/')
path = os.path.normpath(request.match_info["path"])
# Raise error if user try to escape
if path[0] == ".":
if not is_safe_path(path, project.path):
raise aiohttp.web.HTTPForbidden()
path = os.path.join(project.path, path)
await response.stream_file(path)
@Route.post(
@@ -480,15 +479,13 @@ class ProjectHandler:
controller = Controller.instance()
project = await controller.get_loaded_project(request.match_info["project_id"])
path = request.match_info["path"]
path = os.path.normpath(path).strip("/")
path = os.path.normpath(request.match_info["path"])
# Raise error if user try to escape
if path[0] == ".":
if not is_safe_path(path, project.path):
raise aiohttp.web.HTTPForbidden()
path = os.path.join(project.path, path)
response.set_status(200)
response.set_status(201)
try:
async with aiofiles.open(path, 'wb+') as f: