{"record":{"id":"44899ac77970b3c5","repo":"binary-husky/gpt_academic","slug":"path-or-url-44899a","errorCode":null,"errorMessage":"输入文件的路径 ({path_or_url}) 存在，但属于其他用户。请将文件上传后再执行该任务。","messagePattern":"输入文件的路径 \\((.+?)\\) 存在，但属于其他用户。请将文件上传后再执行该任务。","errorType":"exception","errorClass":"FriendlyException","httpStatus":null,"severity":"error","filePath":"shared_utils/fastapi_server.py","lineNumber":69,"sourceCode":"    from toolbox import get_conf, default_user_name\n    from toolbox import FriendlyException\n    PATH_PRIVATE_UPLOAD, PATH_LOGGING = get_conf('PATH_PRIVATE_UPLOAD', 'PATH_LOGGING')\n    sensitive_path = None\n    path_or_url = os.path.relpath(path_or_url)\n    if path_or_url.startswith(PATH_LOGGING):    # 日志文件（按用户划分）\n        sensitive_path = PATH_LOGGING\n    elif path_or_url.startswith(PATH_PRIVATE_UPLOAD):   # 用户的上传目录（按用户划分）\n        sensitive_path = PATH_PRIVATE_UPLOAD\n    elif path_or_url.startswith('tests') or path_or_url.startswith('build'):   # 一个常用的测试目录\n        return True\n    else:\n        raise FriendlyException(f\"输入文件的路径 ({path_or_url}) 存在，但位置非法。请将文件上传后再执行该任务。\") # return False\n    if sensitive_path:\n        allowed_users = [user, 'autogen', 'arxiv_cache', default_user_name]  # three user path that can be accessed\n        for user_allowed in allowed_users:\n            if f\"{os.sep}\".join(path_or_url.split(os.sep)[:2]) == os.path.join(sensitive_path, user_allowed):\n                return True\n        raise FriendlyException(f\"输入文件的路径 ({path_or_url}) 存在，但属于其他用户。请将文件上传后再执行该任务。\") # return False\n    return True\n\ndef _authorize_user(path_or_url, request, gradio_app):\n    from toolbox import get_conf, default_user_name\n    PATH_PRIVATE_UPLOAD, PATH_LOGGING = get_conf('PATH_PRIVATE_UPLOAD', 'PATH_LOGGING')\n    sensitive_path = None\n    path_or_url = os.path.relpath(path_or_url)\n    if path_or_url.startswith(PATH_LOGGING):\n        sensitive_path = PATH_LOGGING\n    if path_or_url.startswith(PATH_PRIVATE_UPLOAD):\n        sensitive_path = PATH_PRIVATE_UPLOAD\n    if sensitive_path:\n        token = request.cookies.get(\"access-token\") or request.cookies.get(\"access-token-unsecure\")\n        user = gradio_app.tokens.get(token)  # get user\n        allowed_users = [user, 'autogen', 'arxiv_cache', default_user_name]  # three user path that can be accessed\n        for user_allowed in allowed_users:\n            # exact match\n            if f\"{os.sep}\".join(path_or_url.split(os.sep)[:2]) == os.path.join(sensitive_path, user_allowed):","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/shared_utils/fastapi_server.py#L51-L87","documentation":"Second stage of the same path guard: when the path IS under PATH_LOGGING or PATH_PRIVATE_UPLOAD, the first path segment must name the requesting user or one of the service users ('autogen', 'arxiv_cache', default_user_name). A path under another user's directory raises FriendlyException — this is per-user isolation preventing cross-user file access on a shared server.","triggerScenarios":"User A sends a request referencing private_upload/<userB>/file.pdf or logging/<userB>/... while authenticated/identified as user A; the join of the first two path segments doesn't match sensitive_path + any allowed user.","commonSituations":"Copy-pasting another user's file path; multi-user deployments where clients hardcode a shared path; stale paths from a previous user identity after re-login.","solutions":["Upload the file yourself so it lands under your own user directory, then use the returned path.","If legitimate sharing is needed, place files under the default_user_name or arxiv_cache subtree that is allow-listed.","Check that the username sent with the request matches the directory owner prefix."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import os\n\ndef path_belongs_to_allowed_user(p: str, sensitive_root: str, user: str,\n                                 allowed=('autogen', 'arxiv_cache', default_user_name)) -> bool:\n    first_two = os.sep.join(os.path.relpath(p).split(os.sep)[:2])\n    return any(first_two == os.path.join(sensitive_root, u)\n               for u in {user, *allowed})\n\nif not path_belongs_to_allowed_user(f, sensitive_path, current_user):\n    f = reupload_to_own_directory(f)","typeGuard":null,"tryCatchPattern":"try:\n    run_api_task(input_file=...)\nexcept FriendlyException as e:\n    if '属于其他用户' in str(e):\n        f = upload_file_first(local_copy)  # get a path under your own user dir\n        run_api_task(input_file=f)","preventionTips":["Always reference files by the path the API returned for YOUR upload.","Don't reuse paths seen in shared logs from other users.","Send the correct username/identity with each request."],"tags":["security","multi-user","authorization","path-validation","fastapi"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}