Change method to prevent forbidden directory traversal. Ref #1894

This commit is contained in:
grossmj committed 2021-05-16 14:29:56 +09:30
1 parent f3d81fa450
commit 2bf16f1e5f
8 files changed
+104 -17

No files matched your search

@@ -19,6 +19,7 @@ API routes for projects.
"""
import os
import urllib.parse
import logging
@@ -198,6 +199,7 @@ async def get_compute_project_file(file_path: str, project: Project = Depends(de
Get a file from a project.
"""
file_path = urllib.parse.unquote(file_path)
path = os.path.normpath(file_path)
# Raise error if user try to escape
@@ -214,6 +216,7 @@ async def get_compute_project_file(file_path: str, project: Project = Depends(de
@router.post("/projects/{project_id}/files/{file_path:path}", status_code=status.HTTP_204_NO_CONTENT)
async def write_compute_project_file(file_path: str, request: Request, project: Project = Depends(dep_project)) -> None:
file_path = urllib.parse.unquote(file_path)
path = os.path.normpath(file_path)
# Raise error if user try to escape
+5 -2
View File
@@ -24,6 +24,7 @@ import tempfile
import zipfile
import aiofiles
import time
import urllib.parse
import logging
@@ -369,7 +370,8 @@ async def get_file(file_path: str, project: Project = Depends(dep_project)) -> F
Return a file from a project.
"""
path = os.path.normpath(file_path).strip("/")
file_path = urllib.parse.unquote(file_path)
path = os.path.normpath(file_path)
# Raise error if user try to escape
if not is_safe_path(path, project.path):
@@ -388,7 +390,8 @@ async def write_file(file_path: str, request: Request, project: Project = Depend
Write a file from a project.
"""
path = os.path.normpath(file_path).strip("/")
file_path = urllib.parse.unquote(file_path)
path = os.path.normpath(file_path)
# Raise error if user try to escape
if not is_safe_path(path, project.path):
+4 -4
View File
@@ -17,6 +17,7 @@
import os
from pathlib import Path
from fastapi import HTTPException, status
from ..config import Config
@@ -37,15 +38,14 @@ def get_default_project_directory():
return path
def is_safe_path(file_path, directory):
def is_safe_path(file_path: str, basedir: str) -> bool:
"""
Check that file path is safe.
(the file is stored inside directory or one of its sub-directory)
"""
requested_path = os.path.abspath(file_path)
common_prefix = os.path.commonprefix([requested_path, directory])
return common_prefix != directory
test_path = (Path(basedir) / file_path).resolve()
return Path(basedir).resolve() in test_path.resolve().parents
def check_path_allowed(path):