Repository navigation
(CWE-22) Path traversal in experimental LocalEnvironment allows file access outside workspace #5869
Description
🔴 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:
python3 -m venv .venv && source .venv/bin/activate && pip install -U pip google-adk- Run the minimal reproduction code below.
- Observe:
/tmp/adk-vrp-traversal-write.txtis created (write outside workspace)/tmp/adk-vrp-traversal-read.txtis 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%)
Activity
er3b07 commentedon May 27, 2026
Verified #5870 branch
04a49ffblocks the PoC (ValueErroron traversal);mainis still vulnerable until that PR merges.Process note: OSS VRP auto-closed my report as duplicate https://issuetracker.google.com/issues/517072165
llalitkumarrr commentedon May 29, 2026
Hello @er3b07,
Thank you for your inputs on the PR. Our team is currently reviewing it, if all checks pass and the reviewer approves the request, it will be merged. We request your patience in the meantime.
er3b07 commentedon Jun 30, 2026
Gentle ping — re-tested today on google-adk 2.3.0 / main; the issue is still reproducible until #5870 lands.
wuliang229 commentedon Jul 13, 2026
Fixed in commit f41bc79
er3b07 commentedon Jul 13, 2026
Thanks @wuliang229 for confirming the fix, and @he-yufeng for implementing it in #5870.
Now that the fix has landed in
f41bc79, could you please consider publishing a security advisory and requesting a CVE? It would also be helpful to confirm the affected versions and the first fixed release, with@er3b07credited as the reporter.I’ve also updated Google OSS VRP report
517072165with the merge details.Thanks again!
fix: keep local environment file access in workspace (backport)
fix: keep local environment file access in workspace (backport)