FoundationAgents/OpenManus · warning · ValueError

Path contains potentially unsafe patterns

Error message

Path contains potentially unsafe patterns

What it means

Raised as ValueError by DockerSandbox._safe_resolve_path (app/sandbox/core/sandbox.py:246) when any single path segment equals '..' — a deliberate path-traversal block before the path is used with Docker APIs. It fires on the raw string segments, so even a benign-looking 'foo/../bar' is rejected; there is no allowlist.

Source

Thrown at app/sandbox/core/sandbox.py:246

        except Exception as e:
            raise RuntimeError(f"Failed to write file: {e}")

    def _safe_resolve_path(self, path: str) -> str:
        """Safely resolves container path, preventing path traversal.

        Args:
            path: Original path.

        Returns:
            Resolved absolute path.

        Raises:
            ValueError: If path contains potentially unsafe patterns.
        """
        # Check for path traversal attempts
        if ".." in path.split("/"):
            raise ValueError("Path contains potentially unsafe patterns")

        resolved = (
            os.path.join(self.config.work_dir, path)
            if not os.path.isabs(path)
            else path
        )
        return resolved

    async def copy_from(self, src_path: str, dst_path: str) -> None:
        """Copies a file from the container.

        Args:
            src_path: Source file path (container).
            dst_path: Destination path (host).

        Raises:
            FileNotFoundError: If source file does not exist.
            RuntimeError: If copy operation fails.

View on GitHub (pinned to 52a13f2a57)

Solutions

  1. Sanitize on the caller side: use os.path.basename for filenames, or normalize and re-verify the result stays under work_dir.
  2. Strip/reject '..' segments (and ideally '..\\' too) before passing user-derived strings.
  3. Use absolute paths already known to be under the work_dir volume.
  4. For user uploads, generate server-side safe names (uuid + sanitized basename).

Example fix

# before
await sandbox.write_file(f"uploads/{user_filename}", data)  # user_filename may contain '..'

# after
safe = os.path.basename(user_filename.replace("..", "_")).strip() or "upload.bin"
await sandbox.write_file(f"uploads/{safe}", data)
Defensive patterns

Strategy: validation

Validate before calling

def safe_container_path(path: str, work_dir: str) -> str:
    parts = [p for p in path.replace("\\", "/").split("/") if p not in ("", ".", "..")]
    candidate = os.path.normpath(os.path.join(work_dir, *parts))
    if not candidate.startswith(os.path.normpath(work_dir)):
        raise ValueError(f"escapes work_dir: {path!r}")
    return candidate

Type guard

def is_safe_path(path: str) -> bool:
    return ".." not in path.replace("\\", "/").split("/")

Try / catch

try:
    await sandbox.write_file(user_path, data)
except ValueError as e:
    if "unsafe patterns" in str(e):
        user_path = os.path.basename(user_path)  # degrade to basename and retry once

Prevention

When it happens

Trigger: Passing a path containing '..' to read_file/write_file/copy_from/copy_to; LLM-generated tool arguments that include traversal; joining an unvalidated user string into a container path; normalizing paths with os.path.normpath on the caller side and still containing '..' segments that escape the root.

Common situations: Agent tool receives ' ../../etc/passwd' style inputs; caller pre-normalizes 'a/./b/../c' — normpath keeps '..' segments when they would climb above the base; Windows-style '..\\' does NOT match the split('/') check and may bypass it (defense depth note).

Related errors


AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15). Data as JSON: /api/errors/011a71cbd6acf89b. Report an issue: GitHub.