Anvil v2.2.25 is a security release. No new commands, no new panes, no configuration to migrate — just a codebase that is measurably harder to attack than it was a week ago. We put Anvil through a deep, adversarially-verified security audit, found fifteen issues worth fixing, and fixed every one of them. This is the write-up.
Why a security-only release
Anvil holds real secrets. It stores your provider API keys in an encrypted vault, it runs a background daemon you can drive from a browser, it shells out to build tools, and it talks to third-party MCP servers you may not fully trust. Each of those is a surface an attacker could aim at. Shipping features on top of surfaces you have not hardened is how small products become cautionary tales — so before the next feature arc, we stopped and audited.
The audit was run as an adversarial exercise. Ten specialist reviewers each took one attack surface — the vault and its cryptography, the OAuth flow, the permissions engine, the sandbox, the daemon IPC, the browser relay, the MCP transport, subprocess execution, deserialization, and secret handling. Every finding a reviewer raised was then handed to three independent skeptics whose only job was to disprove it by reading the actual code. A finding had to survive a majority of those skeptics to count. That process turned an initial pile of candidate issues into fifteen confirmed, reproducible findings — and threw out the ones that did not hold up.
There were no critical vulnerabilities. Four of the surfaces came back clean: the OAuth flow, the vault cryptography (AES-256-GCM under an Argon2id-derived key), the memory safety of every unsafe block in the codebase, and the core permission gate. Those were left untouched. The fixes below are additive and gated, so if you run with the default sandbox posture, Anvil behaves exactly as it did before — only more of the doors are locked.
What we hardened
The browser relay now enforces pairing itself
Anvil can be driven from a browser through a paired relay connection. Previously, once a message reached the host, it was acted on — pairing was enforced by the relay service, not re-checked locally. We closed that: the daemon now verifies pairing at the Rust layer before it will act on any privileged message, so nothing can drive a session, answer its own permission prompts, change configuration, or open an SSH connection without having completed this host’s own pairing handshake (CWE-306 / CWE-862). We also fixed the pairing code’s attempt limit, which could previously be reset by reconnecting (CWE-307).
Windows credential storage is locked down
On Unix, Anvil has always written its secrets with owner-only permissions. On Windows, that protection was missing. Now every secret file — the vault, stored credentials, and the daemon capability token — is written with an owner-only ACL bound at the moment of creation (CWE-732), and the daemon’s local pipe verifies the identity of whatever connects to it (CWE-284). These paths were validated against the actual shipped Windows build, not just reasoned about.
The sandbox denies secrets and network by default
When Anvil runs a command in its sandbox, that command no longer has read access to your credential directories, and known secret environment variables are stripped from it (CWE-522). Under the strict sandbox setting, outbound network is denied by default as well (CWE-668). We also consolidated the macOS enforcement into a single seatbelt profile, removing an older unwired one that implied a protection that was not actually in effect (CWE-1059).
Remote MCP servers can no longer overreach
A malicious or compromised MCP server used to be able to exhaust memory with an unbounded response, or point Anvil at an internal address. Response and message sizes are now capped (CWE-400), and outbound MCP URLs are checked against the IP they actually resolve to — loopback, private, link-local, and cloud-metadata ranges are refused by default, with redirects re-checked on every hop (CWE-918). A trusted internal server can be opted back in explicitly.
And the rest
Secret and run directories are created owner-only (CWE-732 / CWE-367), the deterministic command reviewer no longer misses case and spacing variants (CWE-697), and the /perf argument is validated against a strict allowlist (CWE-77).
How to get it
Upgrade with brew upgrade anvil, or grab a binary from the release page. Seven platforms ship in every release — macOS (Apple Silicon and Intel), Linux (x86_64 and ARM64), Windows, FreeBSD, and NetBSD — and every binary carries a SHA256 checksum published from two independent origins so you can verify what you install.
There is nothing to reconfigure. If you use Anvil on a shared machine, on Windows, or with third-party MCP servers, this is a recommended upgrade. If you do not, it is still a recommended upgrade — the best time to close a door is before anyone tries it.
