mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 22:11:14 +02:00
Clean files and catch file path escape. Ref #1894
This commit is contained in:
1 parent
09ac7fd7fb
commit
f3d81fa450
19 files changed
+44
-601
No files matched your search
@@ -69,13 +69,15 @@ async def download_dynamips_image(filename: str) -> FileResponse:
|
||||
Download a Dynamips IOS image.
|
||||
"""
|
||||
|
||||
dynamips_manager = Dynamips.instance()
|
||||
filename = urllib.parse.unquote(filename)
|
||||
image_path = dynamips_manager.get_abs_image_path(filename)
|
||||
|
||||
if filename[0] == ".":
|
||||
# Raise error if user try to escape
|
||||
if filename[0] == "." or os.path.sep in filename:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
dynamips_manager = Dynamips.instance()
|
||||
image_path = dynamips_manager.get_abs_image_path(filename)
|
||||
|
||||
if not os.path.exists(image_path):
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@@ -108,13 +110,14 @@ async def download_iou_image(filename: str) -> FileResponse:
|
||||
Download an IOU image.
|
||||
"""
|
||||
|
||||
iou_manager = IOU.instance()
|
||||
filename = urllib.parse.unquote(filename)
|
||||
image_path = iou_manager.get_abs_image_path(filename)
|
||||
|
||||
if filename[0] == ".":
|
||||
# Raise error if user try to escape
|
||||
if filename[0] == "." or os.path.sep in filename:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
iou_manager = IOU.instance()
|
||||
image_path = iou_manager.get_abs_image_path(filename)
|
||||
if not os.path.exists(image_path):
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@@ -138,13 +141,13 @@ async def upload_qemu_image(filename: str, request: Request) -> None:
|
||||
@router.get("/qemu/images/{filename:path}")
|
||||
async def download_qemu_image(filename: str) -> FileResponse:
|
||||
|
||||
qemu_manager = Qemu.instance()
|
||||
filename = urllib.parse.unquote(filename)
|
||||
|
||||
# Raise error if user try to escape
|
||||
if filename[0] == ".":
|
||||
if filename[0] == "." or os.path.sep in filename:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
qemu_manager = Qemu.instance()
|
||||
image_path = qemu_manager.get_abs_image_path(filename)
|
||||
|
||||
if not os.path.exists(image_path):
|
||||
|
||||
@@ -32,6 +32,7 @@ from uuid import UUID
|
||||
|
||||
from gns3server.compute.project_manager import ProjectManager
|
||||
from gns3server.compute.project import Project
|
||||
from gns3server.utils.path import is_safe_path
|
||||
from gns3server import schemas
|
||||
|
||||
|
||||
@@ -200,7 +201,7 @@ async def get_compute_project_file(file_path: str, project: Project = Depends(de
|
||||
path = os.path.normpath(file_path)
|
||||
|
||||
# Raise error if user try to escape
|
||||
if path[0] == ".":
|
||||
if not is_safe_path(path, project.path):
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
path = os.path.join(project.path, path)
|
||||
@@ -216,7 +217,7 @@ async def write_compute_project_file(file_path: str, request: Request, project:
|
||||
path = os.path.normpath(file_path)
|
||||
|
||||
# Raise error if user try to escape
|
||||
if path[0] == ".":
|
||||
if not is_safe_path(path, project.path):
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
path = os.path.join(project.path, path)
|
||||
|
||||
@@ -305,11 +305,11 @@ async def get_file(file_path: str, node: Node = Depends(dep_node)) -> Response:
|
||||
path = f"/project-files/{node_type}/{node.id}/{path}"
|
||||
|
||||
res = await node.compute.http_query("GET", f"/projects/{node.project.id}/files{path}", timeout=None, raw=True)
|
||||
return Response(res.body, media_type="application/octet-stream")
|
||||
return Response(res.body, media_type="application/octet-stream", status_code=res.status)
|
||||
|
||||
|
||||
@router.post("/{node_id}/files/{file_path:path}", status_code=status.HTTP_201_CREATED)
|
||||
async def post_file(file_path: str, request: Request, node: Node = Depends(dep_node)) -> dict:
|
||||
async def post_file(file_path: str, request: Request, node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Write a file in the node directory.
|
||||
"""
|
||||
@@ -324,8 +324,8 @@ async def post_file(file_path: str, request: Request, node: Node = Depends(dep_n
|
||||
path = f"/project-files/{node_type}/{node.id}/{path}"
|
||||
|
||||
data = await request.body() # FIXME: are we handling timeout or large files correctly?
|
||||
|
||||
await node.compute.http_query("POST", f"/projects/{node.project.id}/files{path}", data=data, timeout=None, raw=True)
|
||||
# FIXME: response with correct status code (from compute)
|
||||
|
||||
|
||||
@router.websocket("/{node_id}/console/ws")
|
||||
|
||||
@@ -44,6 +44,7 @@ from gns3server.controller.controller_error import ControllerError, ControllerFo
|
||||
from gns3server.controller.import_project import import_project as import_controller_project
|
||||
from gns3server.controller.export_project import export_project as export_controller_project
|
||||
from gns3server.utils.asyncio import aiozipstream
|
||||
from gns3server.utils.path import is_safe_path
|
||||
from gns3server.config import Config
|
||||
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project"}}
|
||||
@@ -371,7 +372,7 @@ async def get_file(file_path: str, project: Project = Depends(dep_project)) -> F
|
||||
path = os.path.normpath(file_path).strip("/")
|
||||
|
||||
# Raise error if user try to escape
|
||||
if path[0] == ".":
|
||||
if not is_safe_path(path, project.path):
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
path = os.path.join(project.path, path)
|
||||
@@ -390,7 +391,7 @@ async def write_file(file_path: str, request: Request, project: Project = Depend
|
||||
path = os.path.normpath(file_path).strip("/")
|
||||
|
||||
# Raise error if user try to escape
|
||||
if path[0] == ".":
|
||||
if not is_safe_path(path, project.path):
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
path = os.path.join(project.path, path)
|
||||
|
||||
Reference in new issue
Block a user