Back to skill

Security audit

claude-code-model

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but it persistently changes Claude Code to use third-party model endpoints and handles API keys in risky ways.

Install only if you intentionally want Claude Code traffic routed to the configured third-party provider. Review the provider URL carefully, avoid pasting untrusted commands, prefer short-lived or restricted API keys, rotate any key exposed in shell history or terminal logs, and be prepared to remove the ANTHROPIC_* variables and ~/.claude config entries to revert.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/configure_model.py:27
Finding

PowerShell Command Injection Through Unescaped Configuration Values

Content
View full analysis

Vulnerability Details

File Location: scripts/configure_model.py, lines 27-35
Vulnerability Type: PowerShell command injection
Risk Level: High

python
commands = [
    f'[Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", "{api_key}", "User")',
    f'[Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "{base_url}", "User")',
    f'[Environment]::SetEnvironmentVariable("ANTHROPIC_MODEL", "{model}", "User")',
    '[Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "", "User")',
]
for cmd in commands:
    subprocess.run(["powershell", "-Command", cmd], check=True)

Technical Analysis

The api_key, base_url, and model command-line arguments are interpolated directly into PowerShell source code. The resulting string is then passed to powershell -Command, causing PowerShell to parse attacker-controlled data as executable language syntax.

Although subprocess.run uses an argument array, this does not prevent injection because the unsafe interpretation occurs inside PowerShell's -Command argument. An attacker can include quotation marks and PowerShell separators or expressions in any interpolated value, terminate the expected string literal, and append arbitrary PowerShell commands.

Attack Path

  1. An attacker supplies a malicious API key, endpoint, or model value, or persuades a user to copy a crafted provider configuration command.
  2. The user runs the script on Windows without the --skip-env option.
  3. The script inserts the malicious value into a PowerShell command string without escaping it.
  4. powershell -Command parses the injected syntax.
  5. The attacker's appended command executes with the privileges of the user running the script.

Impact Assessment

Successful exploitation provides arbitrary command execution under the current user's security context. An attacker could read or modify user-accessible files, steal credentials, alter Cla ...[truncated 347 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not construct PowerShell source code by interpolating user-controlled values.
  • Prefer a native Python mechanism for persistent Windows environment variables, such as writing validated string values through the appropriate winreg user-environment registry interface.
  • If PowerShell must be used, invoke a fixed script whose code is not dynamically generated and transfer values through a non-code data channel. Do not concatenate values into the -Command expression.
  • Validate base_url with a strict URL parser and permit only expected secure schemes such as HTTPS.
  • Validate the model name against the provider's documented character set and reject control characters, line breaks, quotation marks, and shell metacharacters as defense in depth.
  • Add automated Windows tests containing quotation marks, semicolons, command substitutions, and line breaks to verify that inputs are always handled strictly as data.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/configure_model.py:45
Finding

API Key Exposure Through Command-Line Arguments and Terminal Output

Content
View full analysis

Vulnerability Details

File Location: scripts/configure_model.py, lines 45-54 and 128-133; SKILL.md, line 99
Vulnerability Type: Plaintext sensitive-data exposure
Risk Level: Medium

The Unix-like environment-variable output includes the complete API key:

python
env_lines = [
    f'export ANTHROPIC_API_KEY="{api_key}"',
    f'export ANTHROPIC_BASE_URL="{base_url}"',
    f'export ANTHROPIC_MODEL="{model}"',
    'unset ANTHROPIC_AUTH_TOKEN',
]

print(f"Add these lines to your shell profile ({shell_profile}):")
for line in env_lines:
    print(f"  {line}")

The API key is also required as a command-line argument:

python
parser.add_argument("--base-url", required=True, help="API endpoint URL")
parser.add_argument("--model", required=True, help="Model name")
parser.add_argument("--api-key", required=True, help="API key")
parser.add_argument("--skip-env", action="store_true", help="Skip environment variable update")

args = parser.parse_args()

The documented invocation likewise instructs users to place the key on the command line:

bash
python scripts/configure_model.py --base-url URL --model NAME --api-key KEY

Technical Analysis

Supplying an API key through a command-line argument can expose it through interactive shell history and, depending on the operating system and process-inspection permissions, process metadata while the script is running.

On Unix-like systems, update_environment_variables additionally prints an export ANTHROPIC_API_KEY="..." statement containing the complete secret. This can disclose the key through terminal recordings, copied support output, CI logs, remote-session transcripts, screenshots, or other output-capture mechanisms.

Attack Path

  1. A user follows the documented command and enters the API key directly as the value of --api-key.
  2. The command, including the secret, may be retained in shell history or temporar ...[truncated 1041 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove the required --api-key command-line option for ordinary use.
  • Read the key interactively with getpass.getpass() so it is neither echoed nor placed in shell history.
  • For automation, support reading the secret from standard input, a protected file descriptor, or an operating-system secret store rather than from process arguments.
  • Never print the complete API key. Display only a redacted fingerprint if confirmation is necessary.
  • Update SKILL.md so its recommended command does not include a plaintext credential.
  • Warn users that the configuration files contain sensitive values and ensure newly created files receive owner-only permissions where the platform supports them.
  • Recommend immediate credential revocation and rotation if a key has already appeared in logs, shell history, terminal recordings, or shared output.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · SKILL.md (reported line 15)May include surrounding context.

md
Claude Code reads config from multiple sources (in priority order):

1. **Environment variables** (highest priority)
2. **`~/.claude/config.json`**
3. **`~/.claude/settings.json`**

## Required Parameters

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · scripts/configure_model.py (reported line 58)May include surrounding context.

python
Claude Code reads config from multiple sources (in priority order):

1. **Environment variables** (highest priority)
2. **`~/.claude/config.json`**
3. **`~/.claude/settings.json`**

## Required Parameters

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · SKILL.md (reported line 16)May include surrounding context.

md
1. **Environment variables** (highest priority)
2. **`~/.claude/config.json`**
3. **`~/.claude/settings.json`**

## Required Parameters

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · scripts/configure_model.py (reported line 85)May include surrounding context.

python
1. **Environment variables** (highest priority)
2. **`~/.claude/config.json`**
3. **`~/.claude/settings.json`**

## Required Parameters

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

The skill instructs direct modification of a global Claude config file containing API credentials and endpoint settings. Writing to this file can permanently alter agent behavior and expose secrets if the file is readable by other users, synced, or later committed or shared.

Content

Scanner excerpt · SKILL.md (reported line 45)May include surrounding context.

Step 2: Update config.json

Edit ~/.claude/config.json:

json
{

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

The skill directs updates to the global settings file and includes embedding API credentials in that file. Because this file influences future agent behavior, misconfiguration or credential exposure can persist across sessions and affect all subsequent use.

Content

Scanner excerpt · SKILL.md (reported line 59)May include surrounding context.

Step 3: Update settings.json

Edit ~/.claude/settings.json, add/update:

json
{

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
90% confidence
Finding

The skill is specifically designed to redirect Claude Code to external model providers, which can cause future prompts, code, secrets, and workspace content to be transmitted to non-default third parties. In this context, the verification step confirms the reroute is active, making the operational data-exposure risk more significant than a generic model-selection instruction.

Content

Scanner excerpt · SKILL.md (reported line 76)May include surrounding context.

Test the configuration:

bash
claude --print "hi, what model are you?"

Common Issues

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill describes actions that read and modify local agent configuration files and invoke shell commands, but it does not declare any explicit tool scope or allowed-tools boundaries. This increases the chance an agent may execute broader-than-necessary file and shell operations when fulfilling the skill, reducing auditability and least-privilege protections.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs users to persistently store API keys in user environment variables and plaintext config files without any warning about secret exposure, file permissions, shell history, or safer secret storage options. Persisting credentials this way can leak them to other local processes, backups, logs, or accidental file disclosure.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 21)May include surrounding context.

md
python configure_model.py --base-url <url> --model <name> --api-key <key>

Example:
    python configure_model.py --base-url https://api.deepseek.com/anthropic --model deepseek-v4-flash --api-key sk-xxx
"""

import argparse

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 89)May include surrounding context.

md
python configure_model.py --base-url <url> --model <name> --api-key <key>

Example:
    python configure_model.py --base-url https://api.deepseek.com/anthropic --model deepseek-v4-flash --api-key sk-xxx
"""

import argparse

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/configure_model.py (reported line 9)May include surrounding context.

python
python configure_model.py --base-url <url> --model <name> --api-key <key>

Example:
    python configure_model.py --base-url https://api.deepseek.com/anthropic --model deepseek-v4-flash --api-key sk-xxx
"""

import argparse

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
87% confidence
Finding

The script constructs PowerShell command strings by interpolating untrusted values such as api_key, base_url, and model, then passes them to 'powershell -Command'. If any of those values contain PowerShell metacharacters or quote-breaking content, they could alter the command being executed and lead to command injection under the current user context.

Content

Scanner excerpt · scripts/configure_model.py (reported line 37)May include surrounding context.

python
'[Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "", "User")',
        ]
        for cmd in commands:
            subprocess.run(["powershell", "-Command", cmd], check=True)
        print("✓ Environment variables updated")
    else:
        # For Unix-like systems, update shell profile

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script writes the API key directly into ~/.claude/config.json and ~/.claude/settings.json without any explicit warning, consent, or file-permission hardening. Storing long-lived credentials in plaintext on disk increases the risk of credential theft by local malware, other users on a shared system, backups, or accidental disclosure.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/configure_model.py (reported line 113)May include surrounding context.

python
"""Test if Claude Code is using the new model."""
    print("\nTesting configuration...")
    try:
        result = subprocess.run(
            ["claude", "--print", "hi, what model are you?"],
            capture_output=True,
            text=True,

Static analysis

No suspicious patterns detected.