google / google/adk-python

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

オープン
#6,735 コメント 2 件 リアクション 0 件 担当者 1 名 @sanketpatil06 が担当を希望しています GitHub で見る
needs review web
主要言語
Python
スター
21.5k
フォーク
4k
平均マージ
1日 14時間
マージ済み PR(30日)
37

説明

## 🔴 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

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。