{"record":{"id":"c38408e276313915","repo":"langchain-ai/deepagents","slug":"info-filename-unsafe-zip-path","errorCode":null,"errorMessage":"{info.filename}: unsafe zip path","messagePattern":"(.+?): unsafe zip path","errorType":"exception","errorClass":"FleetImportError","httpStatus":null,"severity":"critical","filePath":"libs/talon/deepagents_talon/fleet_import.py","lineNumber":216,"sourceCode":"        lines.append(\"- Review .mcp.json.setup for requested tools and setup details.\")\n    if result.interrupt_tools:\n        lines.append(\n            f\"- Add HITL for sensitive tools with \"\n            f\"{INTERRUPT_ON_TOOLS_ENV_KEY}={','.join(result.interrupt_tools)}.\",\n        )\n    return \"\\n\".join(lines) + \"\\n\"\n\n\ndef _validated_entries(archive: zipfile.ZipFile) -> dict[str, zipfile.ZipInfo]:\n    entries: dict[str, zipfile.ZipInfo] = {}\n    total_size = 0\n    for info in archive.infolist():\n        name = _normalized_zip_name(info.filename)\n        if name is None:\n            continue\n        if _is_unsafe_zip_path(name):\n            msg = f\"{info.filename}: unsafe zip path\"\n            raise FleetImportError(msg)\n        if _is_symlink(info):\n            msg = f\"{name}: symlink entries are not supported\"\n            raise FleetImportError(msg)\n        if info.is_dir():\n            continue\n        _validate_zip_entry_size(name, info)\n        if len(entries) >= _MAX_ZIP_ENTRY_COUNT:\n            msg = f\"{archive.filename}: too many zip entries\"\n            raise FleetImportError(msg)\n        total_size += info.file_size\n        if total_size > _MAX_ZIP_UNCOMPRESSED_BYTES:\n            msg = f\"{archive.filename}: zip uncompressed size exceeds limit\"\n            raise FleetImportError(msg)\n        entries[name] = info\n    return entries\n\n\ndef _normalized_zip_name(name: str) -> str | None:","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/talon/deepagents_talon/fleet_import.py#L198-L234","documentation":"FleetImportError raised by `_validated_entries` (libs/talon/deepagents_talon/fleet_import.py:216) when an archive entry path is deemed unsafe — path traversal or absolute paths. `_normalized_zip_name` normalizes the entry, then `_is_unsafe_zip_path` rejects names that would escape the staging directory (e.g. '../', leading '/', drive letters). This is a zip-slip defense applied before any bytes are written.","triggerScenarios":"Calling `import_fleet_zip` on an archive containing entries like '../evil.py', '/etc/passwd', or names that normalize outside the target. The original `info.filename` is included in the message.","commonSituations":"Archives crafted maliciously (zip-slip attack) or accidentally built with absolute paths (e.g. `zip -r fleet.zip /home/user/.deepagents` on some platforms); third-party fleet exports containing symlinks or traversal entries.","solutions":["Rebuild the archive with relative, root-relative paths only (zip the directory contents, not absolute paths).","Reject/inspect suspicious archives: `python -m zipfile -l fleet.zip` and remove entries starting with '/' or containing '..'.","Only import fleet zips from trusted sources; the library intentionally refuses to sanitize unsafe paths."],"exampleFix":"// before\nzip -r fleet.zip /home/user/.deepagents   # entries like home/user/.deepagents/x or absolute\n// after\ncd /home/user/.deepagents && zip -r ../fleet.zip .   # all entries relative to root","handlingStrategy":"validation","validationCode":"import zipfile, posixpath\ndef archive_paths_are_safe(path) -> bool:\n    with zipfile.ZipFile(path) as z:\n        for name in z.namelist():\n            norm = posixpath.normpath(name.lstrip(\"/\").replace(\"\\\\\", \"/\"))\n            if norm.startswith(\"..\") or posixpath.isabs(name):\n                return False\n    return True","typeGuard":null,"tryCatchPattern":"from deepagents_talon.fleet_import import import_fleet_zip, FleetImportError\ntry:\n    result = import_fleet_zip(source, target)\nexcept FleetImportError as exc:\n    if \"unsafe zip path\" in str(exc):\n        raise SystemExit(f\"{source} contains a path-traversal entry; do not import untrusted archives\") from exc\n    raise","preventionTips":["Only import fleet zips from trusted sources.","Build archives with relative paths rooted at the assistant home.","Screen archives with a zip-slip checker before import; the library refuses rather than sanitizes."],"tags":["security","zip-slip","path-traversal","import"],"backgroundTag":"zip-slip-path-traversal","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}