Skip to content

(CWE-22) Path traversal in experimental LocalEnvironment allows file access outside workspace #5869

Description

@er3b07

🔴 Required Information

Describe the Bug:

LocalEnvironment._resolve_path() in src/google/adk/environment/_local_environment.py uses os.path.join(working_dir, path) without canonicalizing or verifying the path stays under working_dir. Relative paths containing .. escape the workspace, so read_file() and write_file() can read or write files outside the intended directory.

Steps to Reproduce:

  1. python3 -m venv .venv && source .venv/bin/activate && pip install -U pip google-adk
  2. Run the minimal reproduction code below.
  3. Observe:
    • /tmp/adk-vrp-traversal-write.txt is created (write outside workspace)
    • /tmp/adk-vrp-traversal-read.txt is read (read outside workspace)

Expected Behavior:

File operations stay inside the configured working_dir.

Observed Behavior:

write_file("../../../tmp/adk-vrp-traversal-write.txt", ...) and read_file("../../../tmp/adk-vrp-traversal-read.txt") succeed on paths under /tmp, outside the temporary workspace.

Environment Details:

  • ADK Library Version: pip show google-adk (tested on 2.1.0)
  • Desktop OS: Linux
  • Python Version: Python 3.12

Model Information:

  • Are you using LiteLLM: N/A
  • Which model is being used: N/A

🟡 Optional Information

Regression: N/A

Logs: N/A

Additional Context:

dev_server.py / fast_api.py use Path.resolve() and is_relative_to() for agent file paths; LocalEnvironment does not. Different from #5530 (shell-based ranged reads in ReadFileTool).

Minimal Reproduction Code:

import asyncio
import tempfile
from pathlib import Path

from google.adk.environment._local_environment import LocalEnvironment

async def main():
    Path("/tmp/adk-vrp-traversal-read.txt").write_text("SECRET\n")
    Path("/tmp/adk-vrp-traversal-write.txt").unlink(missing_ok=True)

    with tempfile.TemporaryDirectory() as wd:
        env = LocalEnvironment(working_dir=Path(wd))
        await env.initialize()

        await env.write_file(
            "../../../tmp/adk-vrp-traversal-write.txt",
            "written-outside",
        )
        data = await env.read_file("../../../tmp/adk-vrp-traversal-read.txt")

        assert Path("/tmp/adk-vrp-traversal-write.txt").is_file()
        assert data.decode().strip() == "SECRET"
        print("OK: read/write outside workspace")
        await env.close()

asyncio.run(main())

[adk-path-traversal-poc.sh](https://github.com/user-attachments/files/28308150/adk-path-traversal-poc.sh)

**How often has this issue occurred?:**

 - Always (100%)

Metadata

Metadata

Assignees

Labels

core[Component] This issue is related to the core interface and implementationneeds review[Status] The PR/issue is awaiting review from the maintainerv2Affects only 2.0 version

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions