google / google/adk-python

Allow validated `McpToolset` args in local YAML agents served by `adk web`

Đang mở
#6,735 2 bình luận 0 reaction 1 người được giao Được @sanketpatil06 nhận Xem trên GitHub
needs review web
Ngôn ngữ chính
Python
Star
21.5k
Fork
4k
Merge trung bình
1 ngày 22 giờ
Pull request đã merge (30 ngày)
31

Mô tả

## 🔴 Required Information

### Is your feature request related to a specific problem?

Yes.

`adk web` enables a recursive denylist that rejects every YAML key named `args`.
This is an important defense-in-depth mitigation for CVE-2026-4810: a generic tool configuration can combine a Python code reference in `name` with attacker-controlled `args`, causing ADK to import and invoke arbitrary Python code (74f235b).

However, the key-level denylist also rejects built-in tools whose arguments are declarative configuration.
In particular, the existing `McpToolset` YAML sample cannot be loaded by `adk web`:

```yaml
name: retrospective_master
instruction: Use the MCP tools.
model: gemini-3.7-flash
tools:
- name: McpToolset
args:
streamable_http_connection_params:
url: https://hurikaeri-site.viva-tweet-x.workers.dev/mcp
```

The same agent works when constructed in Python or loaded by `adk run`.
Under `adk web`, the local YAML agent fails to load and is absent from the agent loader, so a subsequent `POST /run_sse` returns `404 Not Found`.

https://github.com/google/adk-python/blob/25e8ea6dea82713fdac9bc4117ec425386582b1f/src/google/adk/agents/config_agent_utils.py#L86

https://github.com/google/adk-python/blob/25e8ea6dea82713fdac9bc4117ec425386582b1f/src/google/adk/agents/config_agent_utils.py#L99-L104

### Describe the Solution You'd Like

Replace the all-or-nothing key check for locally loaded YAML with a positive allowlist for security-reviewed ADK built-ins.

For an allowlisted built-in such as the exact literal name `McpToolset`:

1. Do not resolve a module name supplied by YAML.
2. Validate `args` with a fixed ADK-owned Pydantic schema.
3. Reject values that cannot be represented by that schema, including config-supplied callable fields.
4. Construct the fixed ADK-owned tool class through its normal `from_config()` implementation.
5. Continue rejecting `args` for user-defined tools, factories, custom agents, callbacks, and every unregistered built-in.
6. Preserve the existing default rejection of config-supplied stdio MCP servers unless `ADK_ALLOW_CONFIG_STDIO_MCP_SERVERS=1` is explicitly set.

This proposal applies only to configurations loaded from the local agents directory.
Agent Builder uploads should continue rejecting every `args` key until ADK has a separate policy for config-supplied remote MCP URLs and SSRF.

### Impact on your work

This restores the ability to define an `McpToolset` in a local `root_agent.yaml` and use the agent from the ADK Web chat UI, without reopening the generic `name` plus `args` arbitrary-code-execution path.

It also makes the existing config-based MCP sample consistent with `adk web` when the documented stdio opt-in is enabled.

### Willingness to contribute

Yes.

---

## 🟡 Recommended Information

### Describe Alternatives You've Considered

1. Keep rejecting every `args` key.

This closes the reported RCE path but prevents declarative configuration for `McpToolset` and other reviewed built-ins.

2. Add more blocked Python modules.

Module denylists are useful defense in depth, but do not provide a safe path for restoring declarative built-in configuration.
Alias modules and future Python releases also require continuing denylist maintenance.

3. Allow `args` whenever `name` appears to reference `McpToolset`.

This is too broad if arbitrary qualified names or custom agent schemas can opt into the exception.
Matching must be limited to the typed `LlmAgent.tools` position and an exact, statically registered built-in name.

4. Permit the same exception in Agent Builder uploads.

This would also allow uploaded YAML to select remote MCP URLs.
That requires a separate SSRF policy, such as allowed origins or operator-controlled server references, and is intentionally excluded from the initial change.

5. Require Python-based agent definitions.

This is a valid workaround, but makes the checked-in YAML MCP sample
unusable with the ADK Web chat UI.

### Proposed API / Implementation

The user-facing YAML retains its existing shape:

```yaml
name: mcp_agent
model: gemini-3.7-flash
instruction: Use the MCP tools.
tools:
- name: McpToolset
args:
streamable_http_connection_params:
url: https://example.com/mcp
```

Conceptually, validation uses a static registry:

```python
SAFE_BUILTIN_TOOL_ARGS_VALIDATORS = {
"McpToolset": validate_mcp_toolset_args,
}

validator = SAFE_BUILTIN_TOOL_ARGS_VALIDATORS.get(tool.name)
if validator is not None:
validator(tool.args)
return construct_registered_builtin(tool.name, tool.args)

reject_args()
```

The registry key is matched literally and is never passed to `importlib.import_module()`.

For stdio configurations, the existing `ADK_ALLOW_CONFIG_STDIO_MCP_SERVERS=1` operator opt-in remains required.

The exception applies only when `args` appears on a registered tool under the `tools` field of a built-in `LlmAgent`.
A custom agent containing a lookalike `tools` field does not receive the exception.

### Acceptance Criteria

- A local `root_agent.yaml` containing valid registered `McpToolset.args` loads under `adk web`.
- A remote HTTP McpToolset can be constructed without importing a YAML-supplied module.
- A stdio McpToolset remains rejected by default.
- A stdio McpToolset loads only after the existing explicit operator opt-in.
- `args` on user-defined tools and factories remains rejected.
- A callable field such as `httpx_client_factory: os.system` is rejected.
- A custom agent containing a lookalike `tools` field cannot opt into the exception.
- Agent Builder uploads continue rejecting every `args` key.
- Existing module-reference and project-boundary checks continue to pass.

### Additional Context

Related security work:

- CVE-2026-4810 discussion: https://github.com/google/adk-python/discussions/5346
- Restrict Builder YAML code references: https://github.com/google/adk-python/issues/5292
- Restrict arbitrary module imports from YAML: https://github.com/google/adk-python/issues/5822

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.