fix(adk_documentation): confine docs-agent file tools to the managed repos directory#5996
Open
adilburaksen wants to merge 1 commit into
Open
fix(adk_documentation): confine docs-agent file tools to the managed repos directory#5996adilburaksen wants to merge 1 commit into
adilburaksen wants to merge 1 commit into
Conversation
…repos directory The adk_documentation tools are driven by autonomous agents (adk_docs_updater, adk_release_analyzer) that run non-interactively in CI and process untrusted input (issue bodies, release diffs). read_local_git_repo_file_content only checked os.path.isabs(), so any absolute path was read, including files outside the cloned repos under LOCAL_REPOS_DIR_PATH (e.g. $GOOGLE_APPLICATION_CREDENTIALS, /proc/self/environ). list_directory_contents and search_local_git_repo had the same gap, and create_pull_request_from_changes joined caller-provided change keys onto local_path without rejecting '..'. Add _resolve_within_repos_dir() (realpath-resolve + confine to LOCAL_REPOS_DIR_PATH), apply it to the read/list/search tools, and reject change paths that escape the repository root before writing. Add tools_test.py covering these cases. No change for legitimate in-repo paths.
Collaborator
|
Response from ADK Triaging Agent Hello @adilburaksen, thank you for creating this PR! It is a great security improvement for our document-agent tools. To make it easier for our reviewers to review and merge your PR, please ensure it aligns with our Contribution Guidelines. Specifically, we kindly ask you to update the PR description to include the following:
Providing this context will save review time and help us process your contribution faster. Thank you! |
Author
|
Thanks! I've updated the PR description with a Testing Plan section (the five scenarios covered by the new |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
adk_documentationsample tools (read_local_git_repo_file_content,list_directory_contents,search_local_git_repo, and the file-writing step ofcreate_pull_request_from_changes) are invoked by autonomous agents (adk_docs_updater,adk_release_analyzer) that run non-interactively in GitHub Actions and process untrusted input — GitHub issue bodies and release diffs.read_local_git_repo_file_contentonly checksos.path.isabs(file_path)before opening the file. Any absolute path is therefore read, including paths outside the repositories cloned underLOCAL_REPOS_DIR_PATH(e.g. the credentials file referenced byGOOGLE_APPLICATION_CREDENTIALS, or/proc/self/environ).list_directory_contentsandsearch_local_git_repohave the same gap, andcreate_pull_request_from_changesjoins caller-providedchangeskeys ontolocal_pathwithout rejecting.., so a key like../../xwrites outside the repo.Because these tools are LLM-driven over untrusted text, a crafted instruction can steer an agent to read a file outside the workspace and place its contents into a pull request it opens. This change keeps the tools within their intended sandbox.
Change
_resolve_within_repos_dir()thatos.path.realpath-resolves a path (collapsing symlinks and..) and requires the result to stay withinLOCAL_REPOS_DIR_PATH.read_local_git_repo_file_content,list_directory_contents, andsearch_local_git_repo.create_pull_request_from_changes, resolve each target path and reject any that escapes the repository root before writing.tools_test.pycovering: reads/lists/searches outside the sandbox are denied, in-sandbox reads still succeed, a symlink pointing outside is denied, and a traversingchangeskey is rejected without writing.No functional change for legitimate in-repo paths.
Testing Plan
Added
contributing/samples/adk_team/adk_documentation/tools_test.py(unittest), covering both the rejection and the no-regression paths:test_read_outside_sandbox_is_denied—read_local_git_repo_file_contentrejects/etc/passwdand/proc/self/environ.test_read_symlink_escape_is_denied— a symlink inside the sandbox pointing to/etc/passwdis rejected (paths arerealpath-resolved before the check).test_read_inside_sandbox_succeeds— a legitimate file underLOCAL_REPOS_DIR_PATHis still read successfully (no regression).test_list_and_search_outside_sandbox_are_denied—list_directory_contentsandsearch_local_git_reporeject paths outside the sandbox.test_create_pr_rejects_path_traversal_in_changes— achangeskey such as../../../../tmp/evil.txtis rejected and no file is written outside the repo.Test logs