Medium severity6.0NVD Advisory· Published May 11, 2026· Updated May 13, 2026
CVE-2026-45005
CVE-2026-45005
Description
OpenClaw before 2026.4.23 caches resolved webhook route secrets backed by SecretRef values, allowing stale secrets to remain valid after rotation and reload. Attackers with previously valid webhook route secrets can continue authenticating requests and invoking configured webhook task flows until gateway or plugin restart.
Affected products
1Patches
136c4a372a0adfix(webhooks): reload route secrets per request (#70727)
3 files changed · +27 −13
CHANGELOG.md+1 −0 modified@@ -49,6 +49,7 @@ Docs: https://docs.openclaw.ai - Providers/Anthropic Vertex: restore ADC-backed model discovery after the lightweight provider-discovery path by resolving emitted discovery entries, exposing synthetic auth on bootstrap discovery, and honoring copied env snapshots when probing the default GCP ADC path. Fixes #65715. (#65716) Thanks @feiskyer. - Codex harness/status: pin embedded harness selection per session, show active non-PI harness ids such as `codex` in `/status`, and keep legacy transcripts on PI until `/new` or `/reset` so config changes cannot hot-switch existing sessions. - Gateway/security: fail closed on agent-driven `gateway config.apply`/`config.patch` runtime edits by allowlisting a narrow set of agent-tunable prompt, model, and mention-gating paths (including Telegram topic-level `requireMention`) instead of relying on a hand-maintained denylist of protected subtrees that could miss new sensitive config keys. (#70726) Thanks @drobison00. +- Webhooks/security: re-resolve `SecretRef`-backed webhook route secrets on each request so `openclaw secrets reload` revokes the previous secret immediately instead of waiting for a gateway restart. (#70727) Thanks @drobison00. ## 2026.4.22
extensions/webhooks/src/http.test.ts+18 −4 modified@@ -158,9 +158,10 @@ describe("createTaskFlowWebhookRequestHandler", () => { expect(res.statusCode).toBe(401); expect(res.body).toBe("unauthorized"); expect(target.taskFlow.list()).toEqual([]); + expect(hoisted.resolveConfiguredSecretInputStringMock).not.toHaveBeenCalled(); }); - it("caches SecretRef resolution across requests for the same route", async () => { + it("re-resolves SecretRef-backed secrets across requests", async () => { const runtime = createRuntimeTaskFlow(); const target: TaskFlowWebhookTarget = { routeId: "cached", @@ -176,7 +177,10 @@ describe("createTaskFlowWebhookRequestHandler", () => { sessionKey: "agent:main:webhook-cached", }), }; - hoisted.resolveConfiguredSecretInputStringMock.mockResolvedValue({ value: "shared-secret" }); + hoisted.resolveConfiguredSecretInputStringMock + .mockResolvedValueOnce({ value: "shared-secret" }) + .mockResolvedValueOnce({ value: "rotated-secret" }) + .mockResolvedValueOnce({ value: "rotated-secret" }); const handler = createHandlerWithTarget(target); const first = await dispatchJsonRequest({ @@ -195,10 +199,20 @@ describe("createTaskFlowWebhookRequestHandler", () => { action: "list_flows", }, }); + const third = await dispatchJsonRequest({ + handler, + path: target.path, + secret: "rotated-secret", + body: { + action: "list_flows", + }, + }); expect(first.statusCode).toBe(200); - expect(second.statusCode).toBe(200); - expect(hoisted.resolveConfiguredSecretInputStringMock).toHaveBeenCalledTimes(1); + expect(second.statusCode).toBe(401); + expect(second.body).toBe("unauthorized"); + expect(third.statusCode).toBe(200); + expect(hoisted.resolveConfiguredSecretInputStringMock).toHaveBeenCalledTimes(3); }); it("creates flows through the bound session and scrubs owner metadata from responses", async () => {
extensions/webhooks/src/http.ts+8 −9 modified@@ -667,7 +667,6 @@ export function createTaskFlowWebhookRequestHandler(params: { targetsByPath: Map<string, TaskFlowWebhookTarget[]>; inFlightLimiter?: WebhookInFlightLimiter; }): (req: IncomingMessage, res: ServerResponse) => Promise<boolean> { - const secretByTarget = new WeakMap<TaskFlowWebhookTarget, Promise<string | undefined>>(); const rateLimiter = createFixedWindowRateLimiter({ windowMs: WEBHOOK_RATE_LIMIT_DEFAULTS.windowMs, maxRequests: WEBHOOK_RATE_LIMIT_DEFAULTS.maxRequests, @@ -679,19 +678,19 @@ export function createTaskFlowWebhookRequestHandler(params: { maxInFlightPerKey: WEBHOOK_IN_FLIGHT_DEFAULTS.maxInFlightPerKey, maxTrackedKeys: WEBHOOK_IN_FLIGHT_DEFAULTS.maxTrackedKeys, }); - const resolveTargetSecret = (target: TaskFlowWebhookTarget): Promise<string | undefined> => { - const cached = secretByTarget.get(target); - if (cached) { - return cached; + const resolveTargetSecret = async ( + target: TaskFlowWebhookTarget, + ): Promise<string | undefined> => { + if (typeof target.secretInput === "string") { + return target.secretInput; } - const pending = resolveConfiguredSecretInputString({ + const resolved = await resolveConfiguredSecretInputString({ config: params.cfg, env: process.env, value: target.secretInput, path: target.secretConfigPath, - }).then((resolved) => resolved.value); - secretByTarget.set(target, pending); - return pending; + }); + return resolved.value; }; return async (req: IncomingMessage, res: ServerResponse): Promise<boolean> => {
Vulnerability mechanics
AI mechanics synthesis has not run for this CVE yet.
References
3News mentions
21- SecurityScorecard Buys Driftnet for More Internet VisibilityGovInfoSecurity · May 17, 2026
- Four OpenClaw Flaws Enable Data Theft, Privilege Escalation, and PersistenceThe Hacker News · May 15, 2026
- Keycard helps developers secure autonomous AI agents with scoped accessHelp Net Security · May 15, 2026
- Hackers Use AI for Exploit Development, Attack AutomationDark Reading · May 11, 2026
- Exploits and vulnerabilities in Q1 2026Securelist · May 7, 2026
- Hugging Face, ClawHub Abused for Malware DistributionSecurityWeek · May 1, 2026
- 30 ClawHub skills secretly turn AI agents into a crypto swarmThe Register Security · Apr 29, 2026
- 30 ClawHub skills secretly turn AI agents into a crypto swarmThe Register Security · Apr 29, 2026
- 27th April – Threat Intelligence ReportCheck Point Research · Apr 27, 2026
- AI's not going to kill open source code securityThe Register Security · Apr 26, 2026
- Bad Memories Still Haunt AI AgentsDark Reading · Apr 23, 2026
- Agents that remember: introducing Agent MemoryCloudflare Blog · Apr 17, 2026
- The Increasing Role of AI in Vulnerability ResearchWordfence Blog · Apr 10, 2026
- ZDI-26-229: OpenClaw Client PKCE Verifier Information Disclosure VulnerabilityZero Day Initiative · Mar 30, 2026
- ZDI-26-227: OpenClaw Canvas Path Traversal Information Disclosure VulnerabilityZero Day Initiative · Mar 30, 2026
- ZDI-26-228: OpenClaw Canvas Authentication Bypass VulnerabilityZero Day Initiative · Mar 30, 2026
- 16th March – Threat Intelligence ReportCheck Point Research · Mar 16, 2026
- OpenAI's Promptfoo Deal Plugs Agentic AI Testing GapInfosecurity Magazine · Mar 10, 2026
- How AI Assistants are Moving the Security GoalpostsKrebs on Security · Mar 8, 2026
- Risky Business #827 -- Iranian cyber threat actors are down but not outRisky Business · Mar 4, 2026
- Risky Business #826 -- A week of AI mishaps and skulduggeryRisky Business · Feb 25, 2026