harry0703/MoneyPrinterTurbo · warning · ValueError

path is outside the allowed directory

Error message

path is outside the allowed directory

What it means

Raised when os.path.commonpath raises ValueError while comparing the base directory against the resolved candidate. On Windows this happens when the two paths are on different drives (e.g. C:\data vs D:\attack), which by definition cannot be inside the allowed directory. The original exception is chained.

Source

Thrown at app/utils/file_security.py:27

) -> str:
    # 用户传入的路径可能是文件名、相对路径、绝对路径,也可能夹带 `../`。
    # 这里统一解析成真实路径,并用 commonpath 判断它是否仍在允许目录内。
    # 这样比简单判断字符串前缀可靠,可以覆盖符号链接、重复分隔符、相对路径
    # 等场景,适用于上传目录、素材目录、任务产物目录这类白名单目录。
    if not unsafe_path:
        raise ValueError("empty path is not allowed")

    base_dir_real = os.path.realpath(base_dir)
    candidate_path = unsafe_path
    if not os.path.isabs(candidate_path):
        candidate_path = os.path.join(base_dir_real, candidate_path)

    resolved_path = os.path.realpath(candidate_path)
    try:
        common_path = os.path.commonpath([base_dir_real, resolved_path])
    except ValueError as exc:
        # Windows 下不同盘符会触发 ValueError,这类路径一定不属于允许目录。
        raise ValueError("path is outside the allowed directory") from exc

    if common_path != base_dir_real:
        raise ValueError("path is outside the allowed directory")

    if require_file and not os.path.isfile(resolved_path):
        raise ValueError("file does not exist")

    return resolved_path

View on GitHub (pinned to 1f9f19c202)

Solutions

  1. Submit paths that live under the allowed base directory; for absolute paths use the same drive.
  2. Use relative paths under the base directory — they are joined to base_dir before resolution and never hit this branch.

Example fix

# before (Windows)
resolve_path_within_directory(r"C:\app\storage", r"D:\videos\clip.mp4")

# after
resolve_path_within_directory(r"C:\app\storage", "clip.mp4")  # relative to base
Defensive patterns

Strategy: validation

Validate before calling

import os
if os.name == "nt" and os.path.isabs(unsafe_path):
    base_drive = os.path.splitdrive(os.path.realpath(base_dir))[0]
    if os.path.splitdrive(unsafe_path)[0].upper() != base_drive.upper():
        raise ValueError("path must be on the same drive as the storage directory")

Prevention

When it happens

Trigger: On Windows, passing an absolute path on a different drive letter than base_dir (e.g. base 'C:\app\storage', path 'D:\secret.txt'); passing a UNC path (\\\\server\\share) against a mapped drive.

Common situations: Windows deployments where the storage directory is on C: and a client submits a D: path; drive-relative paths like 'D:file.txt' resolving to the D: working directory.

Related errors


AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14). Data as JSON: /api/errors/a601d9b5a0581f5d. Report an issue: GitHub.