assafelovic/gpt-researcher · critical · ValueError

Unsafe blob name: {blob_name}

Error message

Unsafe blob name: {blob_name}

What it means

AzureDocumentLoader._get_blob_path rejects blob names that are absolute paths or contain '..' segments, preventing path traversal outside the temp directory. This is the first guard, on the un-resolved PurePosixPath parts.

Source

Thrown at gpt_researcher/document/azure_document_loader.py:31

        temp_dir = Path(tempfile.mkdtemp()).resolve()
        blobs = self.container.list_blobs()
        file_paths = []
        for blob in blobs:
            blob_client = self.container.get_blob_client(blob.name)
            local_path = self._get_blob_path(temp_dir, blob.name)
            local_path.parent.mkdir(parents=True, exist_ok=True)
            with open(local_path, "wb") as f:
                blob_data = blob_client.download_blob()
                f.write(blob_data.readall())
            file_paths.append(str(local_path))
        return file_paths  # Pass to existing DocumentLoader

    @staticmethod
    def _get_blob_path(temp_dir: Path, blob_name: str) -> Path:
        """Return a safe local path for an Azure blob name."""
        blob_path = PurePosixPath(blob_name.replace("\\", "/"))
        if blob_path.is_absolute() or ".." in blob_path.parts:
            raise ValueError(f"Unsafe blob name: {blob_name}")

        local_path = (temp_dir / Path(*blob_path.parts)).resolve()
        if temp_dir != local_path and temp_dir not in local_path.parents:
            raise ValueError(f"Unsafe blob name: {blob_name}")

        return local_path

View on GitHub (pinned to 6f998577d5)

Solutions

  1. Sanitize blob names: strip leading '/', reject '..' segments before calling load
  2. If legitimate, store blobs under flat names or subpaths without traversal
  3. Keep this exception—do not suppress; it is a security control

Example fix

# before
loader.load(['../etc/passwd'])
# after
safe = [n.lstrip('/') for n in names if '..' not in PurePosixPath(n.replace('\\','/')).parts]
loader.load(safe)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import PurePosixPath
def safe_blob(name: str) -> bool:
    p = PurePosixPath(name.replace("\\", "/"))
    return not p.is_absolute() and ".." not in p.parts
names = [n for n in blob_names if safe_blob(n)]

Type guard

def is_safe_blob_name(name: str) -> bool:
    p = PurePosixPath(str(name).replace("\\", "/"))
    return bool(name) and not p.is_absolute() and ".." not in p.parts

Try / catch

try:
    loader.load(blobs)
except ValueError as e:
    if "Unsafe blob name" in str(e):
        log_security_event(str(e)); skip_and_continue()
    else: raise

Prevention

When it happens

Trigger: A blob named '../secrets.txt', '/etc/passwd', or 'a/../../b' supplied to load(); also Windows-style backslash variants like '..\\..\\x' after backslash-to-slash normalization.

Common situations: Blob names coming from untrusted user input or a compromised container listing; malformed metadata with leading slashes.

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 assafelovic/gpt-researcher@6f998577d5 (2026-08-28). Data as JSON: /api/errors/523de8ef089fa47f. Report an issue: GitHub.