HKUDS/DeepTutor · error · HTTPException

Invalid folder path

Error message

Invalid folder path

What it means

Raised by _sanitize_rel_subdir when a segment of a user-supplied relative folder path equals '..' after normalizing backslashes and stripping whitespace. This is the path-traversal guard that stops writes outside the knowledge base's raw directory.

Source

Thrown at deeptutor/api/routers/knowledge.py:332

    cleaned = _BAD_PATH_CHARS.sub("", segment).strip().strip(".")
    return cleaned[:128]


def _sanitize_rel_subdir(rel_path: str | None) -> str:
    """Return a safe POSIX relative subdir (folders only, no traversal).

    A leading/trailing or interior ``..``/absolute marker raises 400 so a
    crafted directory upload can never escape ``raw/``.
    """
    if not rel_path:
        return ""
    parts: list[str] = []
    for raw_seg in str(rel_path).replace("\\", "/").split("/"):
        seg = raw_seg.strip()
        if seg in ("", "."):
            continue
        if seg == "..":
            raise HTTPException(status_code=400, detail="Invalid folder path")
        safe = _sanitize_path_segment(seg)
        if safe:
            parts.append(safe)
    return "/".join(parts)


def _safe_join_raw(raw_dir: Path, rel_path: str) -> Path:
    """Resolve ``rel_path`` under ``raw_dir``, rejecting traversal."""
    target = (raw_dir / rel_path).resolve()
    try:
        target.relative_to(raw_dir.resolve())
    except ValueError as exc:
        raise HTTPException(status_code=403, detail="Access denied") from exc
    return target


def _save_uploaded_files(
    files: list[UploadFile],

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Reject or strip '..' segments client-side before calling the API
  2. Always build rel paths from sanitized folder names, never from raw OS paths
  3. URL-encode the whole path as a single folder label instead of composing traversal-style paths

Example fix

# before
rel_path = '../../etc'
# after
rel_path = 'notes/lecture1'
Defensive patterns

Strategy: validation

Validate before calling

def safe_rel_path(p):
    parts = [s.strip() for s in str(p).replace('\\','/').split('/')]
    assert '..' not in parts, 'traversal segment'
    return '/'.join(s for s in parts if s not in ('','.'))

Prevention

When it happens

Trigger: Calling folder creation, file move, or upload endpoints with rel_paths/subdir like '../escape', 'a/../../b', or '..\\..\\x'; also '..' hidden behind whitespace (' .. ') since segments are stripped.

Common situations: Frontends passing user-typed folder paths verbatim; clients constructing paths from joined user input; attempts (accidental or malicious) to write outside the KB root.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/5b5ff4f2d603db69. Report an issue: GitHub.