security: add module blocklist for YAML agent config code references#5821
security: add module blocklist for YAML agent config code references#5821Ashutosh0x wants to merge 1 commit into
Conversation
Add a _BLOCKED_MODULES set and _validate_module_reference() function to prevent importing dangerous standard library modules (os, subprocess, builtins, importlib, pickle, etc.) when resolving code references from YAML agent configurations. The existing CVE-2026-4810 fix blocks the 'args' key in YAML configs to prevent passing arguments to constructors. However, the resolve_code_reference(), resolve_fully_qualified_name(), and _resolve_tools() functions still call importlib.import_module() with no restriction on which modules can be imported. This allows an attacker to reference dangerous callables like os.system or subprocess.call in callback, tool, schema, or model code-reference fields. This commit adds validation at all three import points: - resolve_code_reference() (used for callbacks, schemas, model_code) - resolve_fully_qualified_name() (used for agent class resolution) - _resolve_tools() (used for user-defined tool resolution) The blocklist is only enforced when _ENFORCE_DENYLIST is True (set by the web dev server), matching the existing denylist behavior. Includes comprehensive tests verifying: - 11 different blocked modules are rejected in callback fields - 3 blocked modules are rejected in tool fields - Direct resolve_code_reference() calls are blocked - Direct resolve_fully_qualified_name() calls are blocked - google.adk.* modules continue to work (allowlist behavior)
|
Response from ADK Triaging Agent Hello @Ashutosh0x, thank you for creating this PR! This is a great security hardening change. To help the reviewers and ensure alignment with our contribution guidelines, could you please update your PR description or add a comment to include:
This information will help reviewers to review your PR more efficiently. Thanks! |
|
Hi @adk-bot! Here are the test results as requested. Security Validation ResultsAll 5 security tests pass — blocked modules are correctly rejected, and legitimate google.adk modules continue to work: ` === Test 2: subprocess.Popen blocked === === Test 3: builtins.exec blocked === === Test 4: pickle.loads blocked === === Test 5: google.adk.agents.llm_agent.LlmAgent allowed === All security tests completed. Test CoverageThe PR includes 7 new parameterized test functions in
All tests use Happy to address any further feedback! 🙏 |
Fixes #5822
Summary
This PR adds a module blocklist to prevent importing dangerous standard library modules via YAML agent configurations. It is a defense-in-depth hardening that complements the existing args key block from the CVE-2026-4810 fix.
Problem
The CVE-2026-4810 fix blocked the args key in YAML configs to prevent passing arguments to constructors. However, the following functions still call importlib.import_module() with no restriction on which modules can be imported:
This means an attacker could reference dangerous callables like os.system or subprocess.call in callback, tool, schema, or model code-reference fields of a YAML agent config.
Example malicious YAML (currently accepted):
Solution
Added a _BLOCKED_MODULES set containing 28 dangerous standard library modules:
os, subprocess, sys, builtins, importlib, shutil, socket, http, urllib, ctypes, multiprocessing, threading, signal, code, codeop, compileall, runpy, webbrowser, antigravity, pty, commands, pdb, profile, tempfile, shelve, pickle, marshal
Added _validate_module_reference() function that checks the top-level module against the blocklist before any importlib.import_module() call.
Validation is added at all three import points, and is only enforced when _ENFORCE_DENYLIST is True (set by the web dev server), matching existing behavior.
Testing Plan
Unit Tests Added
16 new test cases in tests/unittests/agents/test_agent_config.py:
test_blocked_module_in_callback_raises_when_enforced (parametrized x11) — Verifies that referencing any of 11 blocked stdlib modules (os.system, subprocess.call, subprocess.Popen, builtins.exec, builtins.eval, importlib.import_module, shutil.rmtree, socket.socket, ctypes.cdll, pickle.loads, marshal.loads) in before_agent_callbacks raises ValueError with 'Blocked module reference' message.
test_blocked_module_in_tools_raises_when_enforced (parametrized x3) — Verifies that referencing blocked modules (os.system, subprocess.run, builtins.exec) in tools raises ValueError.
test_resolve_code_reference_blocks_os_when_enforced — Direct unit test for resolve_code_reference() with os.system.
test_resolve_fully_qualified_name_blocks_subprocess_when_enforced — Direct unit test for resolve_fully_qualified_name() with subprocess.Popen.
test_allowed_module_passes_when_enforced — Verifies google.adk modules are NOT blocked (no false positives). Confirms google.adk.agents.llm_agent.LlmAgent resolves correctly.
Verification
All existing tests remain unchanged. The new validation only activates when _ENFORCE_DENYLIST is True, which is only set by the web dev server (adk web), so there is zero risk of regression for CLI or programmatic usage.
CI Results
All automated checks pass:
Files Changed