From be35ad68741b4e289d8cecc1438fb201a7586283 Mon Sep 17 00:00:00 2001 From: Dominik Ziajka Date: Tue, 3 Oct 2017 18:13:19 +0200 Subject: [PATCH] Fixes path normalization during file upload on nodes (Fixes: #2276) --- .../handlers/api/controller/node_handler.py | 3 ++- tests/handlers/api/controller/test_node.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/gns3server/handlers/api/controller/node_handler.py b/gns3server/handlers/api/controller/node_handler.py index f22588a1..9424ea9b 100644 --- a/gns3server/handlers/api/controller/node_handler.py +++ b/gns3server/handlers/api/controller/node_handler.py @@ -367,6 +367,7 @@ class NodeHandler: path = request.match_info["path"] path = force_unix_path(path) + # Raise error if user try to escape if path[0] == ".": raise aiohttp.web.HTTPForbidden @@ -401,7 +402,7 @@ class NodeHandler: project = yield from Controller.instance().get_loaded_project(request.match_info["project_id"]) node = project.get_node(request.match_info["node_id"]) path = request.match_info["path"] - path = os.path.normpath(path) + path = force_unix_path(path) # Raise error if user try to escape if path[0] == ".": diff --git a/tests/handlers/api/controller/test_node.py b/tests/handlers/api/controller/test_node.py index faf0ed2a..c8f2ec4d 100644 --- a/tests/handlers/api/controller/test_node.py +++ b/tests/handlers/api/controller/test_node.py @@ -258,3 +258,20 @@ def test_post_file(http_controller, tmpdir, project, node, compute): response = http_controller.get("/projects/{project_id}/nodes/{node_id}/files/../hello".format(project_id=project.id, node_id=node.id), raw=True) assert response.status == 404 + + +def test_get_and_post_with_nested_paths_normalization(http_controller, tmpdir, project, node, compute): + response = MagicMock() + response.body = b"world" + compute.http_query = AsyncioMagicMock(return_value=response) + response = http_controller.get("/projects/{project_id}/nodes/{node_id}/files/hello\\nested".format(project_id=project.id, node_id=node.id), raw=True) + assert response.status == 200 + assert response.body == b'world' + + compute.http_query.assert_called_with("GET", "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello/nested".format(project_id=project.id, node_id=node.id), timeout=None, raw=True) + + compute.http_query = AsyncioMagicMock() + response = http_controller.post("/projects/{project_id}/nodes/{node_id}/files/hello\\nested".format(project_id=project.id, node_id=node.id), body=b"hello", raw=True) + assert response.status == 201 + + compute.http_query.assert_called_with("POST", "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello/nested".format(project_id=project.id, node_id=node.id), data=b'hello', timeout=None, raw=True)