security: add module blocklist for YAML agent config code references#5821
Open
Ashutosh0x wants to merge 1 commit into
Open
security: add module blocklist for YAML agent config code references#5821Ashutosh0x wants to merge 1 commit into
Ashutosh0x 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)
Collaborator
|
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! |
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.
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