All News

Security Briefing

Investigation10 Vulnerabilities

OpenClaw Quietly Patched 10 Security Vulnerabilities in One Day. Nobody Was Told.

Path traversal. Sandbox escapes. Privilege escalation. Scope-upgrade hijacking. .env injection. All fixed on March 25, 2026. No security advisory. No CVE request. No announcement. I read every PR.

March 26, 20268 min read

Here is what responsible disclosure looks like in 2026: you don't disclose. You merge ten security fixes in a single day, scatter them across pull request numbers that span 450 commits, write clinical commit messages that avoid the word “vulnerability,” and hope nobody reads the diffs.

On March 25, 2026, the OpenClaw project merged fixes for path traversal, sandbox escapes, privilege escalation via WebSocket reconnect, .env injection, scope-upgrade hijacking across two gateway surfaces, and a plugin hook ordering bug that let low-priority plugins override high-priority security decisions. Ten pull requests. Ten security-relevant fixes. Zero advisories.

I want to be precise about what I'm not saying. I'm not saying these were being actively exploited. I'm not saying the OpenClaw maintainers are negligent. What I am saying is this: if you are running an OpenClaw instance — self-hosted, on your infrastructure, with access to your files and your API keys — you deserved to know about these fixes before you had to read a diff to find them.

Let me walk you through what was fixed, and then let's talk about what it means.

3

Critical severity

Path traversal, .env injection, scope-upgrade escalation. Each one is a full compromise vector.

6

High severity

Sandbox escapes, missing scope checks, admin-level mutations from non-admin surfaces.

1

Medium severity

Sandbox config silently ignored. Configuration accepted but never enforced.

Vulnerability Matrix

Ten Fixes. One Day. No Advisory.

Every PR below was merged on March 25, 2026. Sorted by severity.

#54694
Critical

Gateway silent reconnect scope-upgrade escalation

A WebSocket reconnect allowed read-scoped devices to silently auto-approve admin scope upgrades. No user interaction required. No prompt. Just reconnect and you're admin.

Fix: Forces interactive approval for scope-upgrade reconnects.

#54642
Critical

Path traversal in media parse layer

isLikelyLocalPath() accepted ../ and ~ patterns. That means /etc/passwd, ~/.ssh/id_rsa, and .env files were all reachable through the media parser.

Fix: Shared guard function rejecting traversal patterns.

#54631
Critical

Untrusted CWD .env injection

A workspace .env file could redirect config/state paths, override TLS settings, and inject provider base URL redirects. Plant a .env, hijack the entire runtime.

Fix: Filtered loader with blocklists, dotenv.parse() instead of dotenv.config().

#54693
High

Feishu docx upload bypassed localRoots sandbox

File reads from Feishu document uploads weren't constrained to the sandbox. Upload a crafted docx, read anything on the filesystem.

Fix: Enforces localRoots sandbox on Feishu docx upload file reads.

#54561
High

Telegram writeback admin scope gate

Write-scoped gateway callers could trigger persistent config/cron writeback through the Telegram target sink. That's admin-level mutation from a non-admin surface.

Fix: Threads gatewayClientScopes through delivery pipeline, blocks non-admin writebacks.

#54627
High

Host-env blocklist bypass in auth-profile daemon install

Auth-profile environment variable references in daemon install weren't filtered against the host-env blocklist. The blocklist existed. It just wasn't consulted.

Fix: Applies host-env blocklist filtering to auth-profile daemon install.

#54618
High

Reset-profile on lower-privilege browser surfaces

Profile reset was accessible from browser request surfaces that shouldn't have had that privilege. Any browser context could nuke your profile.

Fix: Restricts profile reset to appropriate privilege levels.

#54461
High

Talk-voice config writes missing operator.admin scope check

/voice set config writes weren't enforcing operator.admin scope. Anyone with voice access could rewrite voice configuration.

Fix: Enforces operator.admin scope check on /voice set config writes.

#54241
High

Plugin hooks: lower-priority handler overriding block decisions

A lower-priority plugin returning false could silently neutralize a higher-priority security hook's block: true. Your security plugin says block. A cosmetic plugin says nah. Guess who wins.

Fix: Terminal stickiness + early loop exit for block/cancel decisions.

#54492
Medium

Sandbox alsoAllow and explicit re-allows ignored

The sandbox config accepted alsoAllow entries but the runtime resolver ignored them. Built-in deny list couldn't be overridden even with explicit allows. Configuration theater.

Fix: Runtime resolver now respects alsoAllow and explicit re-allow overrides.

Three Questions Nobody Is Asking

1. Why were all of these found at once?

Ten security fixes don't appear simultaneously by accident. Either someone ran an internal security audit and didn't mention it, or an external researcher reported these through a private channel. Both are fine. Neither excuses the lack of a coordinated advisory. If you're a self-hosted operator running a version from March 24, you have no idea you're exposed. The project's own security policy — which I checked — says vulnerabilities should be reported privately and disclosed responsibly. Responsibly disclosed to whom? Not to the people running the software, apparently.

2. How long were these exploitable?

The path traversal fix (PR #54642) patches isLikelyLocalPath(), a utility function that's been in the codebase for months. The .env injection fix (PR #54631) replaces dotenv.config() with dotenv.parse() — a pattern that was vulnerable from the moment it was written. The WebSocket scope-upgrade escalation (PR #54694) is a logic bug in the gateway reconnect path. These aren't regressions from last week. These are architectural blind spots that have been shipping in every release for an unknown number of months.

3. Why no security advisory?

This is the one that keeps me up. GitHub has a built-in security advisory system. It takes fifteen minutes to file one. The OpenClaw project has 150,000+ stars and an unknown number of self-hosted instances. A path traversal bug that lets the media parser read /etc/passwd and ~/.ssh/id_rsa is not a “minor fix.” A .env injection that can redirect TLS settings and provider base URLs is not a “configuration improvement.” These are the kinds of bugs that get CVE numbers. They should have gotten CVE numbers.

“The difference between a security fix and a security advisory is the difference between protecting your users and protecting your reputation.”

The Uncomfortable Pattern

Look at the attack surfaces covered in a single day: WebSocket gateway, file upload pipeline, workspace environment loading, daemon installation, browser request surfaces, Telegram delivery pipeline, voice configuration, plugin hook ordering, and sandbox resolver. That's not a cluster of bugs in one subsystem. That's a cross-cutting security sweep that touched almost every privilege boundary in the project.

Which means one of two things. Either the project didn't have systematic security review of its privilege boundaries until now, or it did and these slipped through anyway. I'm not sure which answer is more concerning.

The plugin hook fix (PR #54241) is particularly telling. A lower-priority plugin could silently override a higher-priority security hook's block: true decision. Think about what that means in practice: you install a security plugin that blocks sensitive operations, then install a logging plugin with lower priority, and the logging plugin accidentally un-blocks everything the security plugin blocked. The fix adds “terminal stickiness” — once a security hook says block, the decision sticks. This should have been the default behavior from day one. It's the kind of bug that suggests the plugin system was designed for functionality first and security never.

Credit Where It's Due

The fixes themselves are good. The .env injection fix doesn't just patch the immediate problem — it introduces a blocklist architecture that prevents future environment variable abuse. The path traversal fix creates a shared guard function instead of patching the single call site. The gateway scope fix adds interactive approval rather than just blocking reconnects entirely. These are engineering decisions that show someone thought carefully about the right fix, not just the fast one.

But good fixes don't excuse silent disclosure. The people who fixed these bugs did excellent work. The people who decided not to tell anyone about them made a choice that prioritized optics over operator safety.

What I'd Ask the Maintainers

If I had ten minutes with the OpenClaw security team, here's what I'd want to know:

  • Was there an internal audit? If so, who conducted it, and why wasn't the result published as an advisory?
  • How many self-hosted instances are running versions prior to these fixes right now?
  • Is there a plan to request CVEs for the path traversal, .env injection, and scope-upgrade escalation bugs?
  • The Telegram writeback fix threads gatewayClientScopes through the delivery pipeline. Were the other delivery targets — Slack, Discord, Matrix, WeChat — audited for the same scope-gate gap?
  • The sandbox alsoAllow config was accepted but silently ignored. How long has that been the case, and how many operators configured security overrides that were never actually applied?

Ten security fixes. One day. No advisory. The code is safer now. But “safer now” is cold comfort when you didn't know you were at risk yesterday.

DeployClaw News · Security analysis by Carlos Simpson

DeployClaw hosts OpenClaw instances. Upstream fixes ship automatically. This publication covers development independently.

Every security fix. Applied automatically. Zero downtime.

DeployClaw patches your OpenClaw instance the moment upstream merges land. You never have to read a diff to know you're protected.