| Titolo | HKUDS nanobot <= 0.2.1 Incomplete List of Disallowed Inputs (CWE-184) |
|---|
| Descrizione | # Technical Details
An `exec.allowPatterns` allowlist bypass exists in the `ExecTool._guard_command()` / `ExecTool._spawn()` methods in `nanobot/agent/tools/shell.py` of nanobot (pip package `nanobot-ai`).
The application fails to validate each shell segment independently before execution: `_guard_command()` lowercases the full user/model-controlled command string and treats any `re.search()` match of a configured allow-pattern anywhere in that raw string as sufficient approval for the whole command (shell.py#L580-L586), then `_spawn()` executes the exact same raw string with `bash -c` (shell.py#L461-L467), so shell control operators such as `&&` are interpreted after policy approval. A deployment using a loose allowlist such as `\becho\s+allowlisted\b` can be bypassed with `echo allowlisted && touch "canary-created"`, which executes end-to-end through the standard `POST /v1/chat/completions` flow (server.py#L308-L318 -> AgentLoop.process_direct() -> ExecTool._prepare_command() -> _guard_command() approves -> _spawn() runs bash -c). Verified end-to-end with a live `python3 -m nanobot serve` instance plus a deterministic local OpenAI-compatible provider: the vulnerable run returned HTTP 200 with `tool-result:bypass-observed` and created `runtime-vuln/workspace/canary-created`; a control run with allowlist `^echo\s+allowlisted$` returned `tool-result:blocked` and created no canary.
# Vulnerable Code
File: nanobot/agent/tools/shell.py
Method: ExecTool._guard_command() / ExecTool._spawn() (lines 396-402, 461-467, 580-586)
Why: `_guard_command()` approves the whole raw shell string when any configured allow-pattern matches somewhere in it (explicitly_allowed = any(re.search(p, lower) ...)), and `_spawn()` later passes the identical raw string to `bash -c`. The check/execute mismatch lets a chained payload inherit allowlist approval from its first segment, so the appended segment runs with the privileges of the nanobot process.
# Reproduction
1. Deploy nanobot with the exec tool enabled and `tools.exec.allowPatterns` set to a loose prefix/substring regex, e.g. `["\\becho\\s+allowlisted\\b"]`.
2. Download the deterministic local provider `fake_openai_server.py` (https://gist.github.com/YLChen-007/39fd0f0d36aa99a8580ed4d658057f35) and the E2E PoC `verification_test.py` (https://gist.github.com/YLChen-007/bc2f59e30143ffdf9c093b0ef316f6a3), then run `python3 verification_test.py` from the repository root (or use the control script https://gist.github.com/YLChen-007/8a8d6e7a55cce78e0c85824b92948c9e).
3. The script starts a fake provider on 127.0.0.1:18081, a real `python3 -m nanobot serve` on 127.0.0.1:18900, and sends a normal `POST /v1/chat/completions` request that triggers an exec tool call for `echo allowlisted && touch "canary-created"`.
4. Confirm the vulnerable result: HTTP status 200, assistant content `tool-result:bypass-observed`, and file `runtime-vuln/workspace/canary-created` exists.
5. Run the control script: with `^echo\s+allowlisted$` the service returns `tool-result:blocked` and no canary file is created.
# Impact
- Arbitrary command execution policy bypass in the shell execution subsystem for deployments that expose the chat/API interface and rely on `tools.exec.allowPatterns` as a security boundary for the exec tool.
- Commands execute with the privileges of the nanobot process and within the configured workspace/sandbox scope.
- An attacker who can cause the agent to issue an exec tool call can run additional shell segments: modify project files, plant scripts or build artifacts, tamper with agent-managed state, or execute broader host-level actions where stronger sandboxing is not enabled.
- Severity High, CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H. |
|---|
| Fonte | ⚠️ https://github.com/HKUDS/nanobot/issues/5305 |
|---|
| Utente | Eric-a (UID 96353) |
|---|
| Sottomissione | 11/08/2026 15:00 (1 mese fa) |
|---|
| Moderazione | 13/09/2026 18:11 (1 month later) |
|---|
| Stato | Accettato |
|---|
| Voce VulDB | 403310 [HKUDS nanobot fino a 0.2.1 ExecTool shell.py ExecTool._guard_command/ExecTool._spawn escalationi di privilegi] |
|---|
| Punti | 20 |
|---|