BoundBench

Qwen-Agent

Alibaba Qwen team's Python framework for building LLM agents with function calling, a Docker code interpreter, RAG, MCP and a Gradio UI.

github.com/QwenLM/Qwen-Agent · 2026-10-04 · 31a4d36

Defense-in-depth score

2.1 / 10

Minimal

Qwen-Agent is a capable framework with almost no safety primitives of its own. Every model-chosen tool call runs immediately with no approval step, argument checks are limited to JSON types, and document and web tools fetch any URL or read any local file. The Docker code interpreter is a real but unhardened boundary (root, full network, read-write mount), and an exported math agent runs code directly on the host. Treat any deployment that reads untrusted content as able to leak data and change files unattended.

Key gaps (1)

  1. Untrusted web/document content, any local file readable by the process, and unrestricted egress combine in one unattended session with no gate. C5 · Untrusted input blast radius

Criteria

C1 Identity & least privilege

Minimal 0.05 / 1.00

Qwen-Agent has no notion of an agent identity or per-request authorization. It runs with the full authority of the Python process: API keys come from environment variables or config, tools build their own HTTP clients, and file-handling tools read any local path the OS user can read. Nothing narrows that ambient authority or checks a request against a policy, so a hijacked agent acts with everything the process holds.

C2 Approval gates

Minimal 0.00 / 1.00

There is no human-approval step anywhere in the framework. The agent loop hands every model-generated tool call straight to the tool, including code execution, file writes and deletes through the storage tool, and any MCP tool. Developers would have to wrap tools themselves, and nothing in the framework helps them do so. A wrongly chosen call simply runs.

C3 Tool & action scoping

Minimal 0.25 / 1.00

Tool arguments are checked only against their JSON schema types, and not every tool does even that. The document and web tools accept any URL or local path, follow redirects and fetch internal addresses; the storage tool's path handling is not a strict boundary. Code-interpreter and MCP calls skip schema validation entirely. No tools are on by default, but the README's first example turns on code execution.

C4 Code-execution isolation

Minimal 0.42 / 1.00

The built-in code interpreter runs code in a local Docker container and refuses to start if Docker is missing, which is a real boundary. But the container is a stock image running as root with default capabilities, full network egress, and the work directory mounted read-write, and its kernel ports are published on all host interfaces. The framework also exports a math agent whose Python executor runs code directly on the host with exec, and MCP stdio servers run on the host. The mounted host directory can be redirected by an environment variable that a .env file in the working directory can supply.

C5 Untrusted input blast radius

Minimal 0.00 / 1.00

Nothing limits what a hijacked agent can do. Web pages, documents, and MCP tool results and descriptions enter the conversation as ordinary function messages with no provenance marking, and no capability is disabled or gated once untrusted content has been read. With the tools the README demonstrates (document/web reading plus a networked code interpreter), injected text can make the agent send data out and modify files with no human involved.

C6 Memory, context & configuration integrity

Minimal 0.13 / 1.00

Qwen-Agent has no long-term agent memory, but it persists parsed documents in a shared workspace cache keyed only by URL, with no per-user separation or expiry, so content fetched once (including attacker-controlled pages) is re-served to later sessions and users. The storage tool, if enabled, lets the model write arbitrary files that later reads return. The MCP manager also calls load_dotenv(), silently loading a .env file from the current working directory into the process environment.

C7 Third-party extensions

Minimal 0.28 / 1.00

Third-party code enters mainly through MCP servers that the developer lists in code. Nothing is enabled by default and a workspace file cannot add servers, but the README example launches unpinned packages with 'npx -y', there is no version pinning or integrity check, and server-provided tool descriptions go straight into the model's tool list. Stdio servers run as separate host processes; the MCP SDK passes them a minimal default environment unless the config supplies one.

C8 Secrets & sensitive-data protection

Minimal 0.25 / 1.00

API keys are read from environment variables or config and kept in plain process memory. There is no redaction anywhere: debug logging prints full model inputs, and tool exceptions with full tracebacks are returned to the model. On the positive side there is no telemetry, the default log level is INFO, and the code container is started without host environment variables.

C9 Audit & traceability

Minimal 0.25 / 1.00

The framework does not record tool calls. Calls and results appear in the message list returned to the caller, but nothing is persisted, and the only log lines are scattered INFO messages (downloads, container start) and warnings when a tool raises. There is no actor attribution, correlation across sub-agents, or durable trail.

C10 Limits & kill switch

Minimal 0.42 / 1.00

Each agent run is capped at 20 model calls by default, and code-interpreter executions time out after 30 seconds. There is no token, cost, or wall-clock budget, MCP calls and URL downloads wait indefinitely, and a router or group chat starts each sub-agent with a fresh 20-call budget. On exit the framework stops Docker containers and terminates MCP processes.