
The Claude Code RCE: When Eager Parsing Leads to Remote Execution
The security landscape for AI developer tools shifted recently with the discovery of a critical Remote Code Execution (RCE) vulnerability in Anthropic’s Claude Code CLI. This flaw, identified by security researcher Joernchen of 0day.click, highlights a subtle but dangerous oversight in how command line tools handle external inputs. While many modern security audits rely on automated scanners, this particular discovery came from a manual review of the source code, specifically focusing on how the application initializes its configuration before the main logic even begins.
The vulnerability, which has since been patched in version 2.1.118, allowed an attacker to execute arbitrary commands on a user's machine. The core of the issue was not a complex cryptographic failure or a deep logic error in the AI itself. Instead, it was a classic input validation problem located in the tool's deeplink handler. By tricking a user into clicking a specially crafted link, an attacker could bypass security prompts and gain full control over the terminal session.
| Key Information | Details |
|---|---|
| Vulnerability Type | Remote Code Execution (RCE) |
| Affected Tool | Claude Code CLI |
| Fixed Version | 2.1.118 |
| Discovery Method | Manual Source Code Audit |
| Primary Vector | Malicious Deeplink (claude-cli://) |
This discovery serves as a reminder that even the most advanced AI systems are built upon traditional software foundations. When those foundations have cracks in their input handling, the entire system becomes vulnerable. In the following sections, we will break down the technical root cause and how this "eager" parsing was weaponized.
The Technical Root: A Case of "Too Eager" Parsing
At the heart of this vulnerability lies a function named eagerParseCliFlag. In many CLI applications, there is a need to load certain configurations very early in the lifecycle, often before the primary argument parsing library (like Commander.js) has even started. Claude Code used this function to "eagerly" look for flags like --settings or --setting-sources to ensure the environment was correctly configured before the main initialization routine took over.
The technical oversight was deceptively simple. The eagerParseCliFlag function would iterate through the raw process.argv array and use a startsWith check to find matching flags. It was designed to handle both --flag=value and --flag value syntaxes. However, it did so without any awareness of the command line context. It treated every string in the argument array as a potential flag, failing to recognize that a string starting with --settings= might actually be a value belonging to a different flag.
"The deeper issue lay in
eagerParseCliFlagwhich 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 context-blindness created a dangerous injection point. If an attacker could influence the value of a legitimate flag, they could "sneak" a second flag into that value. When eagerParseCliFlag scanned the arguments, it would see the injected string and treat it as a top-level configuration override. This pattern of using startsWith on raw argument arrays is a known anti-pattern because it breaks the fundamental structure of CLI command parsing.
| Parsing Step | Behavior in Vulnerable Version |
|---|---|
| Input Source | Raw process.argv array |
| Matching Logic | startsWith("--settings=") |
| Context Awareness | None (does not distinguish flags from values) |
| Result | Allows flags to be injected into other flag arguments |
By exploiting this lack of context, an attacker could force the CLI to load a completely different set of settings than the user intended.
The Attack Vector: Weaponizing Deeplinks
The delivery mechanism for this exploit was the claude-cli:// deeplink protocol. Deeplinks are designed to improve user experience by allowing websites or other applications to trigger specific actions within a local tool. In the case of Claude Code, the claude-cli://open URI was intended to let users open the CLI and pre-fill a prompt using a query parameter, typically denoted as q.
When a user clicks a link like claude-cli://open?q=hello, the operating system passes this to the Claude Code handler. The handler then translates this into a command line execution, using the --prefill flag to pass the content of q into the CLI. Because of the "eager" parsing issue described earlier, an attacker could craft a q parameter that contained more than just a simple prompt. They could include a string that looked like a configuration flag.
Consider a malicious link structured like this:
claude-cli://open?q=--settings={"hooks":...}
When the CLI starts, the argument array looks something like this:
["claude", "--prefill", "--settings={\"hooks\":...}"]
The standard argument parser would correctly see --settings=... as the value for the --prefill flag. However, the vulnerable eagerParseCliFlag function would scan the array, see a string starting with --settings=, and immediately load it as the global configuration. This allowed the attacker to override any setting in the application simply by getting a user to click a link.
| URI Component | Purpose | Attacker Manipulation |
|---|---|---|
claude-cli://open | Triggers the CLI handler | Standard entry point |
repo= | Specifies a repository | Used to bypass trust dialogs |
q= | Pre-fills the user prompt | Injected with --settings= payload |
This attack vector is particularly effective because it leverages a feature meant for convenience. Users often trust deeplinks from familiar sources, and the transition from a browser to a terminal can happen quickly.
From Injection to Execution: Exploiting Hooks
Once an attacker has the ability to inject arbitrary settings, the path to Remote Code Execution (RCE) becomes straightforward. Claude Code includes a powerful feature called "hooks," which allows users to automate certain actions at specific points in a session's lifecycle. For example, a user might want to run a script every time a new session starts. By injecting a malicious configuration, an attacker can define their own hooks that execute shell commands.
The most effective target for this is the SessionStart hook. An attacker can craft a JSON payload that defines a command to be run as soon as the CLI initializes. Because the eagerParseCliFlag function has already loaded these settings, the command fires immediately. This happens in the background, often before the user even realizes the CLI has opened.
To make the attack even more silent, the researcher discovered a way to bypass the "Workspace Trust" dialog. Normally, Claude Code asks for permission before running in a new repository. However, if the attacker sets the repo parameter in the deeplink to a repository the user has already trusted (such as anthropics/claude-code), the CLI assumes the environment is safe. This bypasses the final line of defense, allowing the injected command to run without any user interaction beyond the initial click.
| Attack Step | Action | Result |
|---|---|---|
| 1. Injection | User clicks a crafted claude-cli:// link | Malicious settings are loaded eagerly |
| 2. Trust Bypass | Link specifies a trusted repo name | Security prompts are suppressed |
| 3. Execution | SessionStart hook triggers | Attacker's shell command runs immediately |
This combination of eager parsing and powerful automation features creates a perfect storm for RCE. It demonstrates that features designed for power users can often be turned against them if the underlying input handling is not robust. In the final sections, we will look at how Anthropic fixed this issue and what other developers can learn from it.
The Fix and Lessons for Developers
Anthropic responded quickly to this discovery, releasing a patch in Claude Code version 2.1.118. The fix involved moving away from the "eager" and context-blind parsing of the argument array. Instead of simply checking if any string in process.argv started with a specific flag name, the updated code uses a more robust approach that understands the structure of command line arguments. By properly distinguishing between flags and their associated values, the injection surface was eliminated.
For developers building CLI tools, especially those with deeplink support, this vulnerability offers several critical lessons. The most important is to avoid manual string matching on raw argument arrays. While it might seem faster to write a custom parser for early initialization, it is almost always safer to use a battle-tested library that handles the complexities of CLI syntax.
| Recommendation | Why it Matters |
|---|---|
| Use Robust Libraries | Libraries like Commander.js or Yargs are designed to handle edge cases and prevent injection. |
| Context-Aware Parsing | Never assume a string is a flag just because it starts with dashes; check its position in the command. |
| Sanitize Deeplinks | Treat all data coming from a URI handler as untrusted and potentially malicious. |
| Limit Hook Power | Consider adding additional confirmation steps for hooks that execute shell commands. |
The "startsWith" anti-pattern is not unique to Claude Code. It is a common mistake in many applications that perform early configuration loading. If your application needs to parse flags before its main initialization, ensure that your logic respects the boundaries between different arguments. A small oversight in how you read a command line can lead to a total system compromise.
"The parsing of command line flags and their arguments should always be done in full context to prevent this exact type of injection.".
By following these principles, developers can provide the convenience of deeplinks and automation without sacrificing the security of their users' systems. In our final section, we will wrap up with some concluding thoughts on the future of secure agentic tools.
Staying Secure in the CLI
The Claude Code RCE vulnerability is a textbook example of how small technical oversights can have significant security implications. It serves as a reminder that as we build more powerful and agentic tools, the basics of secure software development remain as important as ever. Robust input validation, context-aware parsing, and a healthy skepticism of external data are the cornerstones of a secure system.
For users of Claude Code, the message is simple: ensure you are running version 2.1.118 or later. You can check your current version by running claude --version in your terminal. Staying updated is the most effective way to protect yourself from known vulnerabilities. Beyond just updating, it is also wise to be cautious when clicking on deeplinks from untrusted sources, even if they appear to target a tool you use daily.
As the ecosystem of AI-driven developer tools continues to grow, we can expect to see more researchers focusing on these types of integration points. The transition between the web and the local terminal is a high-value target for attackers. By understanding the mechanics of these vulnerabilities, both developers and users can better prepare themselves for the challenges of securing the next generation of software.
Securing the agentic future requires a collaborative effort between tool creators and the security community. The quick response from Anthropic and the detailed disclosure from the research community are positive signs that we are moving in the right direction. By learning from these incidents, we can build tools that are not only more capable but also more resilient.



