odysseus-dev/odysseus · error · HTTPException

Unsafe gallery filename

Error message

Unsafe gallery filename

What it means

Error "Unsafe gallery filename" thrown in odysseus-dev/odysseus.

Source

Thrown at routes/gallery/gallery_routes.py:235

    except Exception:
        return False


def _sanitize_gallery_filename(filename: str) -> str:
    """Return a local filename safe to join under generated_images."""
    safe_name = re.sub(r"[^A-Za-z0-9._-]", "_", Path(str(filename or "")).name)[:128]
    if not safe_name or safe_name in {".", ".."}:
        safe_name = uuid.uuid4().hex[:12]
    return safe_name


GALLERY_IMAGE_DIR = Path(GENERATED_IMAGES_DIR)


def _gallery_image_path(filename: str) -> Path:
    """Resolve a stored gallery filename without leaving generated_images."""
    if not isinstance(filename, str):
        raise HTTPException(400, "Unsafe gallery filename")
    safe_name = _sanitize_gallery_filename(filename)
    original = str(filename or "")
    root = GALLERY_IMAGE_DIR.resolve()
    path = (GALLERY_IMAGE_DIR / safe_name).resolve()
    try:
        if os.path.commonpath([str(root), str(path)]) != str(root):
            raise ValueError
    except Exception:
        raise HTTPException(400, "Unsafe gallery filename")
    if safe_name != original:
        raise HTTPException(400, "Unsafe gallery filename")
    return path


def _normalize_image_endpoint_base(url: str) -> str:
    base = (url or "").strip().rstrip("/")
    if base.endswith("/v1"):
        base = base[:-3].rstrip("/")

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Use a plain filename without path separators or traversal segments.
  2. Rename the file to letters, numbers, dashes, and underscores only.

When it happens

Trigger: Triggered when the corresponding server-side validation or runtime check at the recorded location rejects the request or operation and returns this error message to the caller.

Common situations: See trigger scenarios.


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/65e161f78869b125. Report an issue: GitHub.