agentscope-ai / agentscope-ai/QwenPaw
[Bug]: ToolGuard bypass (_headless_tool_guard) allows Agent to read process env vars in interactive sessions
- Vorherrschende Sprache
- Python
- Sterne
- 34.9k
- Forks
- 3.1k
- Ø Merge
- 1 T. 15 Std.
- Gemergte PRs (30 T.)
- 225
Beschreibung
---
name: Bug Report
about: ToolGuard bypass allows Agent to read process environment variables via execute_shell_command
title: "[Bug]: ToolGuard bypass (_headless_tool_guard) allows Agent to read process env vars in interactive sessions"
labels: ["bug", "security", "triage"]
assignees: []
---
## QwenPaw Version
`1.1.8.post1` (commit `68cd42d2`)
## Description
When using QwenPaw in interactive channels (Console, Web UI, etc.), the entire `tool_guard` security system — including custom rules, `denied_tools`, and `approval_level` — is silently bypassed if `_headless_tool_guard` is `"false"`. This means an Agent can execute arbitrary shell commands including `qwenpaw env list`, which dumps all process environment variables potentially containing API keys, secrets, and other credentials.
**Root cause:** `agents/tool_guard_mixin.py` line 156-158 contains a bypass mechanism with a `# TODO: remove this` comment:
```python
ctx = getattr(self, "_request_context", None) or {}
# TODO: remove this
if ctx.get("_headless_tool_guard", "true").lower() == "false":
return await super()._acting(tool_call) # ← entire guard skipped
```
In interactive (non-headless) sessions, `_headless_tool_guard` is set to `"false"`, so the entire tool guard is skipped regardless of any configured rules or restrictions.
Furthermore, the default `dangerous_shell_commands.yaml` does not include `qwenpaw env` patterns, so even in headless mode where the guard is active, this command would not be flagged.
**Related:** `execute_shell_command` provides unrestricted shell access (no command allowlist/blocklist), making any security rely entirely on the tool_guard system — but the guard itself is bypassable.
## Component(s) Affected
- [x] Core / Backend (app, agents, config, providers, utils, local_models)
- [ ] Console (frontend web UI)
- [ ] Channels (DingTalk, Feishu, QQ, Discord, iMessage, etc.)
- [ ] Skills
- [x] CLI
- [ ] Documentation (website)
- [ ] Tests
- [ ] CI/CD
- [ ] Scripts / Deploy
## Environment
- **QwenPaw version:** `1.1.8.post1` (can also reproduce on `main` branch commit `68cd42d2`)
- **OS:** Windows 11 (AMD64)
- **Install method:** from source (`git clone` + pip install)
- **Python version:** 3.12
## Steps to Reproduce
1. Start QwenPaw in interactive mode (e.g., Console or Web UI)
2. As the Agent, call `execute_shell_command("qwenpaw env list")` or any other arbitrary shell command
3. Observe that the command executes immediately without any tool_guard intervention
**To confirm the bypass specifically:**
1. Configure a custom rule in `config.json` under `security.tool_guard.custom_rules`:
```json
{
"id": "TEST_BLOCK",
"tools": ["execute_shell_command"],
"params": ["command"],
"category": "credential_exposure",
"severity": "HIGH",
"patterns": ["qwenpaw\\s+env"]
}
```
2. Set `approval_level` to `SMART` or `STRICT` for the agent
3. Execute `qwenpaw env list` in the console — it runs without triggering the rule
## Actual vs Expected
- **Actual:** In interactive sessions, `execute_shell_command` bypasses all tool_guard rules. The Agent can read process environment variables (including `ALI_API_KEY`, etc.) without any restriction.
- **Expected:** Tool_guard rules should apply consistently regardless of session type. Commands matching dangerous patterns should be blocked or sent for approval.
## Logs / Screenshots
**Actual execution output:**
```
Key Value
────────────────────────────────────────
ALI_API_KEY 123
```
**Bypass code location:**
```
D:\workspace\gitcode\QwenPaw\src\qwenpaw\agents\tool_guard_mixin.py:156-158
ctx = getattr(self, "_request_context", None) or {}
# TODO: remove this
if ctx.get("_headless_tool_guard", "true").lower() == "false":
return await super()._acting(tool_call)
```
## Additional Notes
This is arguably a design-level concern: `execute_shell_command` has no built-in allowlist/blocklist, so its security posture depends entirely on tool_guard — but tool_guard has a documented bypass for interactive sessions. There is a `# TODO: remove this` comment at the bypass site, indicating it was known to be temporary/unsafe.
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.