Back to skill

Security audit

Crazyrouter Ocr

Security checks for vulnerabilities and agentic risk

Overview

The skill largely performs cloud OCR as advertised, but it can upload full images, prompts, and the API key to an undocumented, unvalidated endpoint override.

Only install this if you are comfortable sending selected images and prompts to Crazyrouter and potentially its model providers. Avoid using it on secrets, credentials, IDs, medical or financial records, or private screenshots. Check your environment before use and do not set CRAZYROUTER_BASE_URL unless you fully trust that endpoint, because it receives the API key and full image data.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.mjs:6
Finding

Unvalidated API endpoint override can expose credentials and image data

Content
View full analysis

Vulnerability Details

File Location: scripts/main.mjs, lines 6 and 46–55
Vulnerability Type: Unvalidated sensitive-data transmission endpoint
Risk Level: Medium

Vulnerable Code

js
const API_BASE = process.env.CRAZYROUTER_BASE_URL || "https://crazyrouter.com/v1";
js
const response = await fetch(`${API_BASE}/chat/completions`, {
  method: "POST",
  headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    model: args.model,
    messages: [{ role: "user", content: [
      { type: "text", text: args.prompt },
      { type: "image_url", image_url: { url: `data:${mimeType};base64,${base64}` } },
    ]}],
    max_tokens: 4096,
  }),
});

Technical Analysis

The script allows CRAZYROUTER_BASE_URL to replace the expected Crazyrouter API endpoint without validating its scheme or hostname. It then sends the CRAZYROUTER_API_KEY as a bearer credential, the user's prompt, and the entire Base64-encoded image to that endpoint.

Sending an image and prompt to the default Crazyrouter service is necessary for the declared cloud OCR functionality. However, transmitting the same sensitive material to an arbitrary, undocumented endpoint exceeds the minimum privileges and network scope required by the Skill. Because HTTPS is not enforced, the override can also specify a plaintext HTTP destination.

Exploitation requires control over, or influence on, the process environment. This could arise from a poisoned shell profile, compromised launcher, CI configuration, container environment, or unsafe user configuration.

Attack Path

  1. An attacker causes CRAZYROUTER_BASE_URL to be set to an attacker-controlled URL, such as https://attacker.example/v1 or an insecure HTTP endpoint.
  2. The user invokes the Skill on a private document, screenshot, receipt, or other image.
  3. The script reads and Base64-encodes the complete image.
  4. The script sends the image, prompt, selected model, ...[truncated 769 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove support for CRAZYROUTER_BASE_URL if custom endpoints are not required, and use a fixed HTTPS endpoint:

    js
    const API_BASE = "https://crazyrouter.com/v1";
    
  2. If endpoint customization is required, parse and validate the URL before reading the image or retrieving the API key:

    js
    const apiUrl = new URL(
      process.env.CRAZYROUTER_BASE_URL || "https://crazyrouter.com/v1"
    );
    
    if (apiUrl.protocol !== "https:") {
      throw new Error("The API endpoint must use HTTPS");
    }
    
    const allowedHosts = new Set(["crazyrouter.com"]);
    if (!allowedHosts.has(apiUrl.hostname)) {
      throw new Error("Untrusted API endpoint");
    }
    
  3. Maintain an explicit allowlist of trusted service hostnames. Do not rely on suffix checks that could accept attacker-controlled domains.

  4. Document any supported endpoint override in SKILL.md, including the fact that the API key, prompt, and full image are transmitted to that destination.

  5. If non-default endpoints must be supported, display the resolved destination and require explicit user approval before transmitting image data or credentials.

  6. Avoid sending the Crazyrouter credential to third-party endpoints. Custom providers should use separate, provider-specific credentials with narrowly scoped permissions.

  7. Ensure error handling does not print response bodies from untrusted endpoints when those bodies may contain reflected secrets or sensitive submitted content.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill documentation does not warn that images and prompts are transmitted to Crazyrouter and potentially onward to underlying model providers such as GPT-4o, Gemini, or Claude. In an OCR/screenshot-analysis skill, this omission is particularly risky because users may submit screenshots, IDs, receipts, medical records, or other sensitive visual data without understanding that it leaves the local environment.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description includes broad trigger phrases like 'read text from image,' 'describe what's in an image,' and 'analyze a screenshot,' which are common user requests and can cause the skill to be invoked in many contexts. Because the skill sends image content to a third-party API, overly broad invocation increases the chance of unintentionally routing sensitive screenshots or documents to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script reads a local image file, base64-encodes it, and sends the full image contents to a third-party API endpoint, but it does not provide an explicit runtime warning or consent step before exfiltrating potentially sensitive image data. In the context of an OCR/screenshot-analysis skill, users may provide screenshots containing credentials, personal data, or internal documents, so silent remote upload materially increases privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/main.mjs:7