Back to skill

Security audit

Clawd Throttle

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its advertised LLM cost-routing purpose, but its optional HTTP proxy and endpoint settings can expose paid model accounts if enabled or misconfigured.

Review before installing. Keep HTTP proxy mode disabled unless you can bind it to loopback and protect it with authentication; do not expose port 8484 to a LAN or the internet. Use restricted provider API keys, verify every configured base URL, and secure the local config file if it contains credentials.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/index.ts:59
Finding
Unauthenticated HTTP Proxy Binds to All Network Interfaces<![CDATA[ ## Vulnerability Details **File Location**: `src/index.ts:59-65`; `src/server/http-proxy.ts:29-79`; `src/server/http-handlers.ts:102-146` **Vulnerability Type**: Missing authentication and unsafe network binding **Risk Level**: High ### Vulnerable Code ```ts // src/index.ts:59-65 const httpEnabled = config.http.enabled || flags.http || flags['http-only']; if (httpEnabled) { const { createHttpProxy } = await import('./server/http-proxy.js'); const httpServer = createHttpProxy({ config, registry, weights, logWriter, logReader, routingTable }); httpServer.listen(config.http.port, () => { log.info(`HTTP proxy listening on http://localhost:${config.http.port}`); }); } ``` ```ts // src/server/http-proxy.ts:29-39 const server = http.createServer(async (req, res) => { // CORS headers res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.setHeader( 'Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, X-Throttle-Force-Model', ); res.setHeader( 'Access-Control-Expose-Headers', 'X-Throttle-Model, X-Throttle-Tier, X-Throttle-Score, X-Throttle-Request-Id', ); ``` ```ts // src/server/http-proxy.ts:61-79 if (req.method === 'POST') { if (pathname !== '/v1/messages' && pathname !== '/v1/chat/completions') { sendError(res, 404, 'not_found', `Unknown route: POST ${pathname}`); return; } // Parse request body const body = await readBody(req); if (pathname === '/v1/messages') { await handleMessages(body, req, res, handlerDeps); } else { await handleChatCompletions(body, req, res, handlerDeps); } return; } ``` ### Technical Analysis Calling `httpServer.listen(config.http.port)` without specifying a hostname normally binds the server to the unspecified address, potentially exposing it on all available IPv4 or IPv6 interfaces. The informational log incorrectly describes the listener as `localhost`, which can ...[truncated 2059 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bind to loopback explicitly by default: ```ts httpServer.listen(config.http.port, '127.0.0.1', () => { log.info(`HTTP proxy listening on http://127.0.0.1:${config.http.port}`); }); ``` 2. Provide a separate, explicit configuration option for external binding and display a prominent security warning when it is enabled. 3. Require a dedicated proxy authentication token on all non-health endpoints. Compare tokens with a timing-safe comparison. 4. Do not treat incoming provider-style `Authorization` headers as authentication unless they are explicitly validated. 5. Replace wildcard CORS with a configurable allowlist. Disable browser CORS access by default. 6. Apply per-client rate limits, request quotas, concurrency limits, and conservative maximum-token limits. 7. Restrict model-forcing headers to authenticated and authorized clients. 8. Consider disabling `/stats` remotely or protecting it with the same authentication mechanism. 9. Add tests confirming that unauthenticated requests are rejected and that the default listener is loopback-only. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
src/config/index.ts:27
Finding
Unvalidated Provider Endpoints Receive API Credentials and Complete Prompts<![CDATA[ ## Vulnerability Details **File Location**: `src/config/index.ts:27-31`; `src/proxy/anthropic.ts:8-35`; `src/proxy/google.ts:8-35`; `src/proxy/openai-compat.ts:8-48` **Vulnerability Type**: Sensitive data exposure through unvalidated network destinations **Risk Level**: High ### Vulnerable Code ```ts // src/config/index.ts:27-31 if (fs.existsSync(configFilePath)) { const raw = fs.readFileSync(configFilePath, 'utf-8'); fileConfig = JSON.parse(raw) as Partial<ThrottleConfig>; } const config = deepMerge( defaults as unknown as Record<string, unknown>, fileConfig as Record<string, unknown>, ) as unknown as ThrottleConfig; ``` ```ts // src/proxy/anthropic.ts:8-35 export async function callAnthropic( request: ProxyRequest, config: ThrottleConfig, ): Promise<ProxyResponse> { const url = `${config.anthropic.baseUrl}/v1/messages`; const startMs = performance.now(); const body: Record<string, unknown> = { model: request.modelId, max_tokens: request.maxTokens, messages: request.messages.map(m => ({ role: m.role, content: m.content, })), }; if (request.systemPrompt) { body.system = request.systemPrompt; } if (request.temperature !== undefined) { body.temperature = request.temperature; } const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', ...buildAnthropicAuthHeaders(config), 'anthropic-version': '2023-06-01', }, body: JSON.stringify(body), }); ``` ```ts // src/proxy/google.ts:8-35 export async function callGoogle( request: ProxyRequest, config: ThrottleConfig, ): Promise<ProxyResponse> { const url = `${config.google.baseUrl}/v1beta/models/${request.modelId}` + `:generateContent?key=${config.google.apiKey}`; const startMs = performance.now(); const contents = request.messages.map(m => ({ role: m.role === 'assistant' ? 'model' : 'user', parts: [{ text: m.content }], })); const bod ...[truncated 4304 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate provider URLs with the `URL` API before use. 2. Require HTTPS for every remote provider. Permit plain HTTP only for explicitly recognized loopback destinations such as local Ollama. 3. Maintain an allowlist of official hostnames for built-in provider credentials. 4. Separate official-provider mode from custom gateway mode. Do not automatically attach an official API key to a custom hostname. 5. Require explicit, informed confirmation before forwarding credentials or prompts to a nonstandard endpoint. 6. Consider maintaining separate credentials for custom gateways rather than reusing official provider credentials. 7. Reject URLs containing embedded credentials, unexpected schemes, fragments, or ambiguous hostnames. 8. Mitigate DNS rebinding and server-side request forgery risks if externally supplied endpoints are supported. 9. Use a supported authentication header for Google instead of a query-string key where the API permits it. Otherwise, ensure URLs are never written to logs and document the residual exposure. 10. Create configuration files and directories with restrictive permissions, such as directory mode `0700` and file mode `0600`. 11. Update the privacy documentation to state explicitly that prompt content is forwarded to the selected provider even though plaintext prompts are not stored locally. 12. Apply equivalent validation to streaming implementations in `anthropic-stream.ts`, `google-stream.ts`, and `openai-compat-stream.ts`. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/setup.sh:17
Finding
Setup Installs Unlocked Dependency Versions and Permits Lifecycle Script Execution<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:17-20`; `package.json:18-27` **Vulnerability Type**: Non-reproducible dependency installation and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```sh # scripts/setup.sh:17-20 # Install dependencies echo "" echo "Installing dependencies..." npm install ``` ```json // package.json:18-27 "dependencies": { "@modelcontextprotocol/sdk": "^1.22.0", "zod": "^3.25.0" }, "devDependencies": { "tsx": "^4.19.0", "typescript": "^5.6.0", "vitest": "^2.1.0" } ``` The audited project structure contains no `package-lock.json`. ### Technical Analysis The setup process executes `npm install` while dependency versions are specified with caret ranges and no lockfile is included. The exact package and transitive-dependency versions installed can therefore change between installations without any change to the audited project. By default, npm may execute dependency lifecycle scripts during installation. If a compatible dependency or transitive dependency is compromised, a subsequent setup can download and execute code that was not part of the reviewed artifact. No evidence was found that the currently declared package names are typosquatted or intentionally malicious. The vulnerability is the absence of reproducible dependency resolution and installation hardening. ### Attack Path 1. A direct or transitive dependency publishes a compromised version satisfying one of the declared semantic-version ranges. 2. A user runs `scripts/setup.sh` or otherwise executes `npm install`. 3. npm resolves the newly published compatible version because no reviewed lockfile constrains the dependency graph. 4. npm downloads the compromised package. 5. A malicious lifecycle script executes during installation, or malicious runtime code executes when the Skill starts. 6. The package receives the privileges of the user running setup and may access files, environment variables, and network resources ...[truncated 606 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate and commit a reviewed `package-lock.json`. 2. Replace setup-time `npm install` with `npm ci` so installation fails if dependency metadata differs from the lockfile. 3. Review and update the lockfile through a controlled dependency-update process. 4. Pin security-sensitive dependencies more narrowly where practical. 5. Run `npm audit` and software-composition analysis in continuous integration. 6. Evaluate installation with `npm ci --ignore-scripts` if none of the selected packages require lifecycle scripts. 7. If lifecycle scripts are required, inventory and review the packages that execute them. 8. Verify package integrity and provenance through registry integrity hashes, trusted publishing metadata, and dependency-signing controls where available. 9. Separate production dependencies from development tooling in deployment artifacts. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (70)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill openly exposes configuration inspection, mode changes, local logging, and persistent config storage in addition to routing. Because it handles API keys and provider metadata, under-describing these administrative capabilities increases the chance of secret mishandling, unauthorized configuration changes, or leakage of operational metadata through diagnostic commands.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
}

  // Provider API keys
  if (process.env['ANTHROPIC_API_KEY']) {
    config.anthropic.apiKey = process.env['ANTHROPIC_API_KEY'];
  }
  if (process.env['ANTHROPIC_AUTH_TYPE']) {
Confidence
70% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
}

  // Provider API keys
  if (process.env['ANTHROPIC_API_KEY']) {
    config.anthropic.apiKey = process.env['ANTHROPIC_API_KEY'];
  }
  if (process.env['ANTHROPIC_AUTH_TYPE']) {
Confidence
70% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
if (process.env['ANTHROPIC_BASE_URL']) {
    config.anthropic.baseUrl = process.env['ANTHROPIC_BASE_URL'];
  }
  if (process.env['GOOGLE_AI_API_KEY']) {
    config.google.apiKey = process.env['GOOGLE_AI_API_KEY'];
  }
  if (process.env['OPENAI_API_KEY']) {
Confidence
70% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
if (process.env['ANTHROPIC_BASE_URL']) {
    config.anthropic.baseUrl = process.env['ANTHROPIC_BASE_URL'];
  }
  if (process.env['GOOGLE_AI_API_KEY']) {
    config.google.apiKey = process.env['GOOGLE_AI_API_KEY'];
  }
  if (process.env['OPENAI_API_KEY']) {
Confidence
70% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
if (process.env['GOOGLE_AI_API_KEY']) {
    config.google.apiKey = process.env['GOOGLE_AI_API_KEY'];
  }
  if (process.env['OPENAI_API_KEY']) {
    config.openai.apiKey = process.env['OPENAI_API_KEY'];
  }
  if (process.env['DEEPSEEK_API_KEY']) {
Confidence
70% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
if (process.env['GOOGLE_AI_API_KEY']) {
    config.google.apiKey = process.env['GOOGLE_AI_API_KEY'];
  }
  if (process.env['OPENAI_API_KEY']) {
    config.openai.apiKey = process.env['OPENAI_API_KEY'];
  }
  if (process.env['DEEPSEEK_API_KEY']) {
Confidence
70% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
if (process.env['OPENAI_API_KEY']) {
    config.openai.apiKey = process.env['OPENAI_API_KEY'];
  }
  if (process.env['DEEPSEEK_API_KEY']) {
    config.deepseek.apiKey = process.env['DEEPSEEK_API_KEY'];
  }
  if (process.env['XAI_API_KEY']) {
Confidence
70% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
if (process.env['OPENAI_API_KEY']) {
    config.openai.apiKey = process.env['OPENAI_API_KEY'];
  }
  if (process.env['DEEPSEEK_API_KEY']) {
    config.deepseek.apiKey = process.env['DEEPSEEK_API_KEY'];
  }
  if (process.env['XAI_API_KEY']) {
Confidence
70% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Static analysis

No suspicious patterns detected.