Many years ago, I lived in a shared house with a handful of friends. We called it The Jaguar House, as a little homage to the song by Illya Kuryaki and the Valderramas. There were six bedrooms and huge common spaces where we rehearsed, recorded, made music, and hung out.
The first week we lived there, we had a situation that still sticks with me.
After a rehearsal, everyone left and only the housemates were inside. We were playing videogames when a friend who didn’t live there came to the door, opened it with a key, and came in unannounced. He had gone to the bakery with a full confidence, returned with bread, and used a key he hadn’t been given.
I remember feeling a sharp and immediate discomfort. I couldn’t immediately tell if that reaction was just paranoia: I was young, privacy-obsessed, maybe overthinking. But I could quickly tell everyone living there felt the same thing. It was a boundary. It looked like abuse of trust.
If you also feel uncomfortable with that behavior, then let me tell you: Anthropic is doing the same thing on your computer.
This article contains the implications of this behavior, an analysis in plain language, and a full technical reproduction at the end.
The findings
I first found Alexander Hanff’s Anthropic secretly installs spyware when you install Claude Desktop article. The accusation is severe, so I decided to reproduce and expand the investigation on my end with strict controls. The setup was simple:
- restart Claude in a controlled way,
- capture pre- and post-launch system state,
- collect and narrow logs to the exact launch window,
- validate that the same behavior persists after moving and restoring candidate manifest directories.
Across these runs, the result was consistent.
Claude Desktop writes the same native messaging manifest into seven Chromium-family browser locations in one pass: Chrome, Brave, Edge, Vivaldi, Opera, Arc, and Chromium. It does so even for browsers that are not installed on your system.
The manifest content is the same in every location, including:
- the same helper binary path,
- the same list of
allowed_origins, - the same hash identity.
This is not a random residue in one directory. It is a coordinated, multi-target host registration.
Wait, is that bad?
This is where the security model matters. Native messaging manifests are permission files that allow browser extensions to invoke a local executable. That executable runs at user level outside the browser sandbox. This is effectively giving a local, pre-authorized execution bridge access through several browsers. This is a very dark pattern. If you install one desktop application, it sets up a broader local bridge footprint than most people expect.
But why is it concerning?
If any allowlisted extension ID is compromised, spoofed, or mishandled in its update path, it could use that bridge to trigger local actions through the browser-native host mechanism.
That creates two practical risks:
-
Cross-browser lateral expansion A single trust anchor can become a pathway in multiple browser environments.
-
User session surface growth The bridge can participate in browser automation and session-aware behavior, which magnifies privacy impact if abused. In practice, if any allowlisted extension is compromised in its update path, and you open your (e.g.) bank account on one of these browsers, an attacker would have access to it.
I do not claim this means exploitation is definitely happening. I am saying the capability exists, is intentionally installed by design, and broadens the local attack surface.
Is it true?
Yes. I reproduced this in a controlled environment. I:
- removed manifest files
- captured pre-launch state
- restarted Claude
- captured post-launch state
- inspected manifest contents, hashes, metadata, and logs
I did this to avoid claiming causation from historical noise. The outcome is deterministic enough to treat as verified behavior, not a one-off.
It feels like an asshole-ish move
It is. Anthropic’s desktop product is widely trusted and positioned as safety-focused; Anthropic has been investing a lot of money to position itself as the company that didn’t want to hand its models to the US military due to safety concerns. That is exactly why this kind of cross-boundary host setup should be explicit.
Installing a desktop app should not equal silently configuring cross-browser native capabilities without clear, discoverable opt-in and ongoing visibility. I did not ask for the key to be taken. I did not give anybody permission to walk in. And yet, somebody just entered my house.
Am I supposed to just trust you and your blog?
You are not. If you want to verify this on your own machine (and by all means, please do so), you can follow these instructions on your MacBook. I am not a Windows user and haven’t verified what happens there.
While I’m listing basic reproduction steps ran on my own, you can check Alexander Hanff’s original article with other reproduction steps and further codesign, ticket stapling, and provenance analysis.
WARNING: This removes Claude native-host manifests from the listed browser paths. It can break Claude-related browser extension integration until Claude writes them again.
Run this block as one paste from a normal terminal session: it sets the target paths, checks baseline state, wipes manifests, relaunches Claude, and checks if they come back. If the first post-relaunch pass still says missing, wait a few seconds and run the last check again. This is written for macOS zsh and uses command -p so it does not depend on your shell PATH.
#!/usr/bin/env zsh
# 1) Define the manifest filename and Chromium-family browser paths to check.
MANIFEST_NAME="com.anthropic.claude_browser_extension.json"
TARGET_DIRS=(
"$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts"
"$HOME/Library/Application Support/BraveSoftware/Brave-Browser/NativeMessagingHosts"
"$HOME/Library/Application Support/Microsoft Edge/NativeMessagingHosts"
"$HOME/Library/Application Support/Vivaldi/NativeMessagingHosts"
"$HOME/Library/Application Support/com.operasoftware.Opera/NativeMessagingHosts"
"$HOME/Library/Application Support/Arc/User Data/NativeMessagingHosts"
"$HOME/Library/Application Support/Chromium/NativeMessagingHosts"
)
# 1a) Use the system hash utility without relying on PATH.
HASH_CMD=(command -p shasum -a 256)
echo "=== Baseline: existing manifests and hashes ==="
# 2) Capture what exists before we touch anything.
for dir in "${TARGET_DIRS[@]}"; do
path="$dir/$MANIFEST_NAME"
if [ -f "$path" ]; then
echo "FOUND: $path"
"${HASH_CMD[@]}" "$path"
else
echo "MISSING: $path"
fi
done
# 3) Remove manifests to force a clean registration event on relaunch.
for dir in "${TARGET_DIRS[@]}"; do
command -p rm -f "$dir/$MANIFEST_NAME"
done
# 4) Restart Claude fully so any manifest registration can happen again.
command -p pkill -x Claude || true
command -p sleep 2
command -p open -a Claude
command -p sleep 5
# 5) Verify post-relaunch state. Matching paths/hashes here indicate launch-driven behavior.
echo "=== Post-relaunch recreated manifests and hashes ==="
for dir in "${TARGET_DIRS[@]}"; do
path="$dir/$MANIFEST_NAME"
if [ -f "$path" ]; then
echo "RECREATED: $path"
"${HASH_CMD[@]}" "$path"
else
echo "STILL MISSING: $path"
fi
done
If the same seven paths come back with matching hash output after restart, this behavior is reproducible and launch-driven, not leftover artifact noise.
Conclusion
I am publishing this because what happened in that old house taught me what trust feels like: I expect boundaries to be respected, I expect informed access, and I expect nobody crosses the lines quietly. If a desktop application wants local browser integration, then make it damn clear. Scope it narrowly. Install it only on the existing browsers present in the system, and ask first. Let users see what was installed and remove it easily.
That is not a radical ask. It is the minimum you need when local machine access and active user sessions are involved.