fix: enforce path boundary in built-in agent file tools and restrict YAML callback invocation#5413
Conversation
|
Hi @adilburaksen , Thank you for your contribution! We appreciate you taking the time to submit this pull request. Please fix formatting errors by running autoformat.sh |
|
Fixed — ran |
|
Hi @rohityan — happy to provide any additional context.
Both issues are triggered through agent config loading or session state manipulation. Let me know if you'd like a more detailed write-up or additional test coverage for specific scenarios. |
f5ecc81 to
629925f
Compare
…YAML callback invocation resolve_root_directory.py: - Add _validate_root_directory() to reject absolute paths and '..' in session-state-supplied root_directory (mirrors cbcb5e6 for file_artifact_service) - Enforce project root boundary in resolve_file_path() via .relative_to() for both absolute and relative input paths config_agent_utils.py: - Restrict resolve_code_reference() to only invoke callables with args when the resolved object is a class constructor (inspect.isclass()). Plain functions and built-ins (e.g. os.system) cannot be called with args from YAML config.
629925f to
30c76c7
Compare
|
Hi @rohityan — updating you on the status of this PR. The YAML callback RCE portion of this PR ( I've opened a replacement PR that focuses exclusively on the remaining path traversal issue in PR #5615 is rebased on the current I'll close this PR (#5413) in favour of #5615. Please feel free to review #5615 when you get a chance. Thank you for your time and the earlier response. |
|
Superseded by #5615 (path-traversal-only, rebased on current main, no conflicts). |
Summary
This PR fixes two security issues in the Agent Builder Assistant's file tools and YAML agent config loading.
Fix 1 — Path boundary enforcement in
resolve_file_path()(resolve_root_directory.py)Issue:
resolve_file_path()accepted absolute paths without checking whether they were within the project root, and trustedroot_directoryfrom session state without validation. This allowed file operations outside the intended project directory.Fix:
_validate_root_directory()that rejects absolute paths, null bytes, backslashes, and..components in session-state-suppliedroot_directory(mirrors the same pattern applied in commitcbcb5e6forfile_artifact_service.py).relative_to()for both absolute and relative inputsFix 2 — Restrict callable invocation in
resolve_code_reference()(config_agent_utils.py)Issue:
resolve_code_reference()called any Python callable with attacker-supplied args from YAML config at deserialization time. This allowed specifying dangerous built-ins (e.g.os.system) as callbacks with arbitrary arguments.Fix: Only invoke a callable with
argswhen the resolved object is a class constructor (inspect.isclass()). Plain functions cannot be called with args from YAML config; they are returned as references for the framework to invoke at the appropriate time.Testing
Both fixes are verified with unit tests confirming:
root_directory: "/"injection is blockedos.systemand other non-class callables with args are blocked in YAML config