fix(security): keep plain audit off plugin runtimes · openclaw/openclaw@f858b5d
vincentkoc
·
2026-05-01
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -42,6 +42,7 @@ Docs: https://docs.openclaw.ai
|
42 | 42 | - Discord/voice: lengthen the default voice join Ready wait, add configurable `voice.connectTimeoutMs`/`voice.reconnectGraceMs`, and warn before destroying unrecovered disconnected sessions so slow Discord voice handshakes and reconnects no longer fail silently. Fixes #63098; refs #39825 and #65039. Thanks @darealgege, @kzicherman, and @ayochim. |
43 | 43 | - Gateway/health: refresh cached health RPC snapshots when channel runtime state diverges, so Discord and other channel status reads no longer report stale running or connected values until the cache TTL expires. (#75423) Thanks @clawsweeper. |
44 | 44 | - Gateway/sessions: keep session-store reads from running stale prune and entry-count cap maintenance during startup, so oversized stores no longer block chat history readiness after updates while writes and `sessions cleanup --enforce` still preserve the cleanup safeguards. Fixes #70050. Thanks @tangda18. |
| 45 | +- Security/audit: keep plain `security audit` on the cold config/filesystem path and reserve plugin runtime security collectors for `--deep`, so large plugin installs cannot execute every plugin runtime during routine audits. Thanks @vincentkoc. |
45 | 46 | - Discord/voice: merge configured media-understanding providers such as Deepgram into partial active provider registries, so follow-up voice turns keep transcribing after another media plugin is already active. Fixes #65687. Thanks @OneMintJulep. |
46 | 47 | - WhatsApp: stage `qrcode` through root mirrored runtime dependencies so packaged QR pairing can render from staged plugin-runtime-deps installs. Fixes #75394. Thanks @FelipeX2001. |
47 | 48 | - Discord/voice: apply per-channel Discord `systemPrompt` overrides to voice transcript turns by forwarding the trusted channel prompt through the voice agent run. Fixes #47095. Thanks @qearlyao. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -25,6 +25,8 @@ openclaw security audit --fix
|
25 | 25 | openclaw security audit --json |
26 | 26 | ``` |
27 | 27 | |
| 28 | +Plain `security audit` stays on the cold config/filesystem/read-only path. It does not discover plugin runtime security collectors by default, so routine audits do not load every installed plugin runtime. Use `--deep` to include best-effort live Gateway probes and plugin-owned security audit collectors; explicit internal callers may also opt into those plugin-owned collectors when they already have an appropriate runtime scope. |
| 29 | + |
28 | 30 | The audit warns when multiple DM senders share the main session and recommends **secure DM mode**: `session.dmScope="per-channel-peer"` (or `per-account-channel-peer` for multi-account channels) for shared inboxes. |
29 | 31 | This is for cooperative/shared inbox hardening. A single Gateway shared by mutually untrusted/adversarial operators is not a recommended setup; split trust boundaries with separate gateways (or separate OS users/hosts). |
30 | 32 | It also emits `security.trust_model.multi_user_heuristic` when config suggests likely shared-user ingress (for example open DM/group policy, configured group targets, or wildcard sender rules), and reminds you that OpenClaw is a personal-assistant trust model by default. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -41,7 +41,10 @@ export function registerSecurityCli(program: Command) {
|
41 | 41 | () => |
42 | 42 | `\n${theme.heading("Examples:")}\n${formatHelpExamples([ |
43 | 43 | ["openclaw security audit", "Run a local security audit."], |
44 | | - ["openclaw security audit --deep", "Include best-effort live Gateway probe checks."], |
| 44 | + [ |
| 45 | + "openclaw security audit --deep", |
| 46 | + "Include best-effort live Gateway probes and plugin-owned security audit collectors.", |
| 47 | + ], |
45 | 48 | ["openclaw security audit --deep --token <token>", "Use explicit token for deep probe."], |
46 | 49 | [ |
47 | 50 | "openclaw security audit --deep --password <password>", |
@@ -55,7 +58,7 @@ export function registerSecurityCli(program: Command) {
|
55 | 58 | security |
56 | 59 | .command("audit") |
57 | 60 | .description("Audit config + local state for common security foot-guns") |
58 | | -.option("--deep", "Attempt live Gateway probe (best-effort)", false) |
| 61 | +.option("--deep", "Attempt live Gateway probes and plugin-owned collector checks", false) |
59 | 62 | .option("--token <token>", "Use explicit gateway token for deep probe auth") |
60 | 63 | .option("--password <password>", "Use explicit gateway password for deep probe auth") |
61 | 64 | .option("--fix", "Apply safe fixes (tighten defaults + chmod state/config)", false) |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -23,7 +23,7 @@ vi.mock("../plugins/runtime/metadata-registry-loader.js", () => ({
|
23 | 23 | loadPluginMetadataRegistrySnapshotMock(...args), |
24 | 24 | })); |
25 | 25 | |
26 | | -const { collectPluginSecurityAuditFindings } = await import("./audit.js"); |
| 26 | +const { collectPluginSecurityAuditFindings, runSecurityAudit } = await import("./audit.js"); |
27 | 27 | |
28 | 28 | function createAuditContext(params: { |
29 | 29 | sourceConfig: Parameters<typeof collectPluginSecurityAuditFindings>[0]["sourceConfig"]; |
@@ -152,4 +152,26 @@ describe("security audit read-only plugin scope", () => {
|
152 | 152 | expect(applyPluginAutoEnableMock).not.toHaveBeenCalled(); |
153 | 153 | expect(loadPluginMetadataRegistrySnapshotMock).not.toHaveBeenCalled(); |
154 | 154 | }); |
| 155 | + |
| 156 | +it("keeps plain security audit off plugin collector runtime discovery by default", async () => { |
| 157 | +const sourceConfig = { |
| 158 | +plugins: { |
| 159 | +allow: ["audit-plugin"], |
| 160 | +}, |
| 161 | +}; |
| 162 | + |
| 163 | +await runSecurityAudit({ |
| 164 | +config: sourceConfig, |
| 165 | + sourceConfig, |
| 166 | +env: {}, |
| 167 | +includeFilesystem: false, |
| 168 | +includeChannelSecurity: false, |
| 169 | +stateDir: "/tmp/openclaw-test-state", |
| 170 | +configPath: "/tmp/openclaw-test-config.json", |
| 171 | +}); |
| 172 | + |
| 173 | +expect(getActivePluginRegistryMock).not.toHaveBeenCalled(); |
| 174 | +expect(applyPluginAutoEnableMock).not.toHaveBeenCalled(); |
| 175 | +expect(loadPluginMetadataRegistrySnapshotMock).not.toHaveBeenCalled(); |
| 176 | +}); |
155 | 177 | }); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -946,7 +946,7 @@ async function createAuditExecutionContext(
|
946 | 946 | execDockerRawFn: opts.execDockerRawFn, |
947 | 947 | probeGatewayFn: opts.probeGatewayFn, |
948 | 948 | plugins: opts.plugins, |
949 | | -loadPluginSecurityCollectors: opts.loadPluginSecurityCollectors !== false, |
| 949 | +loadPluginSecurityCollectors: opts.loadPluginSecurityCollectors ?? deep, |
950 | 950 | workspaceDir, |
951 | 951 | configSnapshot, |
952 | 952 | codeSafetySummaryCache: opts.codeSafetySummaryCache ?? new Map<string, Promise<unknown>>(), |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。