| Titel | nextlevelbuilder GoClaw 3.13.2 Command Execution Policy Bypass (CWE-184) |
|---|
| Beschreibung | # Technical Details
A Command Execution Policy Bypass exists in the `matchesAllowlist` method in `internal/tools/exec_approval.go` of GoClaw.
The application fails to validate wrapper-carried shell commands under `tools.execApproval.allowlist`. The public `POST /v1/tools/invoke` endpoint accepts attacker-controlled `args.command`, `extractBin(command)` returns only the first token after optional environment assignments, and `ExecTool.Execute()` later runs the original string via `/bin/sh -c`. If `env` is allowlisted, `env sh -c 'touch canary.txt'` is approved even though the inner payload should be blocked.
# Vulnerable Code
File: internal/tools/exec_approval.go
Method: matchesAllowlist
Why: `extractBin(command)` returns the basename of the first token and `matchesAllowlist()` compares that to the allowlist. The execution path in `internal/tools/shell.go` then executes `cmd = exec.Command(shellPath, "-c", command)`, preserving the full attacker-supplied shell chain.
# Reproduction
1. Configure GoClaw `3.13.2` with `tools.execApproval.security=allowlist` and put `env` in `tools.execApproval.allowlist`.
2. Send `POST /v1/tools/invoke` to `exec` with `args.command` set to `env sh -c 'touch canary.txt'`.
3. Confirm that the direct payload `touch canary.txt` is denied but the wrapped payload is accepted and creates the canary file.
# Impact
- Authenticated operators can smuggle blocked commands behind allowlisted wrappers.
- The allowlist protects only the first token, not the full shell behavior that reaches the host. |
|---|
| Quelle | ⚠️ https://github.com/nextlevelbuilder/goclaw/issues/1202 |
|---|
| Benutzer | Eric-b (UID 96354) |
|---|
| Einreichung | 11.06.2026 09:10 (vor 1 Monat) |
|---|
| Moderieren | 13.07.2026 19:23 (1 month later) |
|---|
| Status | Duplikat |
|---|
| VulDB Eintrag | 378127 [nextlevelbuilder GoClaw 3.11.3 exec_approval.go ExecApprovalManager.CheckCommand erweiterte Rechte] |
|---|
| Punkte | 0 |
|---|