mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix(security): clarify denyCommands exact-match guidance
This commit is contained in:
@@ -29,7 +29,7 @@ It also emits `security.trust_model.multi_user_heuristic` when config suggests l
|
|||||||
For intentional shared-user setups, the audit guidance is to sandbox all sessions, keep filesystem access workspace-scoped, and keep personal/private identities or credentials off that runtime.
|
For intentional shared-user setups, the audit guidance is to sandbox all sessions, keep filesystem access workspace-scoped, and keep personal/private identities or credentials off that runtime.
|
||||||
It also warns when small models (`<=300B`) are used without sandboxing and with web/browser tools enabled.
|
It also warns when small models (`<=300B`) are used without sandboxing and with web/browser tools enabled.
|
||||||
For webhook ingress, it warns when `hooks.defaultSessionKey` is unset, when request `sessionKey` overrides are enabled, and when overrides are enabled without `hooks.allowedSessionKeyPrefixes`.
|
For webhook ingress, it warns when `hooks.defaultSessionKey` is unset, when request `sessionKey` overrides are enabled, and when overrides are enabled without `hooks.allowedSessionKeyPrefixes`.
|
||||||
It also warns when sandbox Docker settings are configured while sandbox mode is off, when `gateway.nodes.denyCommands` uses ineffective pattern-like/unknown entries, when `gateway.nodes.allowCommands` explicitly enables dangerous node commands, when global `tools.profile="minimal"` is overridden by agent tool profiles, when open groups expose runtime/filesystem tools without sandbox/workspace guards, and when installed extension plugin tools may be reachable under permissive tool policy.
|
It also warns when sandbox Docker settings are configured while sandbox mode is off, when `gateway.nodes.denyCommands` uses ineffective pattern-like/unknown entries (exact node command-name matching only, not shell-text filtering), when `gateway.nodes.allowCommands` explicitly enables dangerous node commands, when global `tools.profile="minimal"` is overridden by agent tool profiles, when open groups expose runtime/filesystem tools without sandbox/workspace guards, and when installed extension plugin tools may be reachable under permissive tool policy.
|
||||||
It also flags `gateway.allowRealIpFallback=true` (header-spoofing risk if proxies are misconfigured) and `discovery.mdns.mode="full"` (metadata leakage via mDNS TXT records).
|
It also flags `gateway.allowRealIpFallback=true` (header-spoofing risk if proxies are misconfigured) and `discovery.mdns.mode="full"` (metadata leakage via mDNS TXT records).
|
||||||
It also warns when sandbox browser uses Docker `bridge` network without `sandbox.browser.cdpSourceRange`.
|
It also warns when sandbox browser uses Docker `bridge` network without `sandbox.browser.cdpSourceRange`.
|
||||||
It also flags dangerous sandbox Docker network modes (including `host` and `container:*` namespace joins).
|
It also flags dangerous sandbox Docker network modes (including `host` and `container:*` namespace joins).
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ If more than one person can DM your bot:
|
|||||||
- **Browser control exposure** (remote nodes, relay ports, remote CDP endpoints).
|
- **Browser control exposure** (remote nodes, relay ports, remote CDP endpoints).
|
||||||
- **Local disk hygiene** (permissions, symlinks, config includes, “synced folder” paths).
|
- **Local disk hygiene** (permissions, symlinks, config includes, “synced folder” paths).
|
||||||
- **Plugins** (extensions exist without an explicit allowlist).
|
- **Plugins** (extensions exist without an explicit allowlist).
|
||||||
- **Policy drift/misconfig** (sandbox docker settings configured but sandbox mode off; ineffective `gateway.nodes.denyCommands` patterns; dangerous `gateway.nodes.allowCommands` entries; global `tools.profile="minimal"` overridden by per-agent profiles; extension plugin tools reachable under permissive tool policy).
|
- **Policy drift/misconfig** (sandbox docker settings configured but sandbox mode off; ineffective `gateway.nodes.denyCommands` patterns because matching is exact command-name only (for example `system.run`) and does not inspect shell text; dangerous `gateway.nodes.allowCommands` entries; global `tools.profile="minimal"` overridden by per-agent profiles; extension plugin tools reachable under permissive tool policy).
|
||||||
- **Runtime expectation drift** (for example `tools.exec.host="sandbox"` while sandbox mode is off, which runs directly on the gateway host).
|
- **Runtime expectation drift** (for example `tools.exec.host="sandbox"` while sandbox mode is off, which runs directly on the gateway host).
|
||||||
- **Model hygiene** (warn when configured models look legacy; not a hard block).
|
- **Model hygiene** (warn when configured models look legacy; not a hard block).
|
||||||
|
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ export const FIELD_HELP: Record<string, string> = {
|
|||||||
"gateway.nodes.allowCommands":
|
"gateway.nodes.allowCommands":
|
||||||
"Extra node.invoke commands to allow beyond the gateway defaults (array of command strings). Enabling dangerous commands here is a security-sensitive override and is flagged by `openclaw security audit`.",
|
"Extra node.invoke commands to allow beyond the gateway defaults (array of command strings). Enabling dangerous commands here is a security-sensitive override and is flagged by `openclaw security audit`.",
|
||||||
"gateway.nodes.denyCommands":
|
"gateway.nodes.denyCommands":
|
||||||
"Commands to block even if present in node claims or default allowlist.",
|
"Node command names to block even if present in node claims or default allowlist (exact command-name matching only, e.g. `system.run`; does not inspect shell text inside that command).",
|
||||||
nodeHost:
|
nodeHost:
|
||||||
"Node host controls for features exposed from this gateway node to other nodes or clients. Keep defaults unless you intentionally proxy local capabilities across your node network.",
|
"Node host controls for features exposed from this gateway node to other nodes or clients. Keep defaults unless you intentionally proxy local capabilities across your node network.",
|
||||||
"nodeHost.browserProxy":
|
"nodeHost.browserProxy":
|
||||||
|
|||||||
@@ -365,6 +365,31 @@ describe("handleSystemRunInvoke mac app exec host routing", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("denies semicolon-chained shell payloads in allowlist mode without explicit approval", async () => {
|
||||||
|
const payloads = ["openclaw status; id", "openclaw status; cat /etc/passwd"];
|
||||||
|
for (const payload of payloads) {
|
||||||
|
const command =
|
||||||
|
process.platform === "win32"
|
||||||
|
? ["cmd.exe", "/d", "/s", "/c", payload]
|
||||||
|
: ["/bin/sh", "-lc", payload];
|
||||||
|
const { runCommand, sendInvokeResult } = await runSystemInvoke({
|
||||||
|
preferMacAppExecHost: false,
|
||||||
|
security: "allowlist",
|
||||||
|
ask: "on-miss",
|
||||||
|
command,
|
||||||
|
});
|
||||||
|
expect(runCommand, payload).not.toHaveBeenCalled();
|
||||||
|
expect(sendInvokeResult, payload).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
ok: false,
|
||||||
|
error: expect.objectContaining({
|
||||||
|
message: "SYSTEM_RUN_DENIED: approval required",
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it("denies nested env shell payloads when wrapper depth is exceeded", async () => {
|
it("denies nested env shell payloads when wrapper depth is exceeded", async () => {
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -955,11 +955,11 @@ export function collectNodeDenyCommandPatternFindings(cfg: OpenClawConfig): Secu
|
|||||||
severity: "warn",
|
severity: "warn",
|
||||||
title: "Some gateway.nodes.denyCommands entries are ineffective",
|
title: "Some gateway.nodes.denyCommands entries are ineffective",
|
||||||
detail:
|
detail:
|
||||||
"gateway.nodes.denyCommands uses exact command-name matching only.\n" +
|
"gateway.nodes.denyCommands uses exact node command-name matching only (for example `system.run`), not shell-text filtering inside a command payload.\n" +
|
||||||
detailParts.map((entry) => `- ${entry}`).join("\n"),
|
detailParts.map((entry) => `- ${entry}`).join("\n"),
|
||||||
remediation:
|
remediation:
|
||||||
`Use exact command names (for example: ${examples.join(", ")}). ` +
|
`Use exact command names (for example: ${examples.join(", ")}). ` +
|
||||||
"If you need broader restrictions, remove risky commands from allowCommands/default workflows.",
|
"If you need broader restrictions, remove risky command IDs from allowCommands/default workflows and tighten tools.exec policy.",
|
||||||
});
|
});
|
||||||
|
|
||||||
return findings;
|
return findings;
|
||||||
|
|||||||
Reference in New Issue
Block a user