Back to skill

Security audit

Kimi Use

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Kimi API helper, but it needs review because it can send prompts, selected image files, and the API key to an arbitrary configured API host without validation.

Install only if you trust the publisher and the environment that will launch it. Keep KIMI_API_HOST on the documented Kimi endpoint unless you deliberately intend to use another service, protect and rotate the API key if exposed, and avoid sending sensitive screenshots, IDs, documents, or private text unless you are comfortable uploading them to the configured remote API.

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/index.js:18
Finding

Unvalidated Custom API Host Can Expose Credentials and User Data

Content
View full analysis

Vulnerability Details

File Location: scripts/index.js, lines 18–19, 49–58, and 97–117
Vulnerability Type: Unrestricted outbound destination with bearer credential forwarding
Risk Level: Medium

Vulnerable Code

javascript
const KIMI_API_KEY = process.env.KIMI_API_KEY;
const KIMI_API_HOST = process.env.KIMI_API_HOST || 'https://api.kimi.com/coding';
javascript
const resp = await fetch(`${KIMI_API_HOST}/v1/messages`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${KIMI_API_KEY}`,
    'Content-Type': 'application/json',
    'anthropic-version': '2023-06-01',
    'x-api-provider': 'kimi',
  },
  body: JSON.stringify(body),
});

The image-analysis path performs the same request pattern:

javascript
const resp = await fetch(`${KIMI_API_HOST}/v1/messages`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${KIMI_API_KEY}`,
    'Content-Type': 'application/json',
    'anthropic-version': '2023-06-01',
    'x-api-provider': 'kimi',
  },
  body: JSON.stringify({
    model,
    messages: [{
      role: 'user',
      content: [
        { type: 'image', source: { type: 'base64', media_type: mimeType, data: imageData } },
        { type: 'text', text: prompt }
      ]
    }],
    temperature,
    max_tokens,
  }),
});

Technical Analysis

KIMI_API_HOST is accepted directly from the process environment and used to construct the outbound request URL. The implementation does not enforce HTTPS, validate the hostname, restrict the port, or require explicit approval for a non-default destination.

Every request includes the KIMI_API_KEY as a bearer credential. Depending on the invoked function, the body can also contain chat messages, conversation history, translation input, system prompts, image prompts, and complete local image contents encoded as base64.

Sending this information to the documented default K ...[truncated 1927 chars]

Remediation
View remediation

Remediation Suggestions

  1. Allowlist the production endpoint. Accept https://api.kimi.com/coding by default and reject unrecognized hosts unless custom endpoints are an explicit functional requirement.
  2. Require secure transport. Parse the configured value with URL and require the https: protocol. Reject embedded credentials, fragments, and unexpected ports.
  3. Separate credentials by destination. Never forward the production Kimi credential to arbitrary custom endpoints. Require a separately configured credential for each approved custom host.
  4. Require explicit unsafe opt-in. If custom hosts must remain supported, require a dedicated flag such as KIMI_ALLOW_CUSTOM_HOST=true and display the exact destination before transmitting credentials or files.
  5. Confirm file uploads. Clearly notify users that local image contents will be uploaded to the configured host, particularly when it differs from the documented default.
  6. Apply redirect restrictions. Ensure requests do not follow redirects to untrusted origins while retaining the authorization header. Prefer disabling redirects or validating every redirect destination.
  7. Minimize credential scope. Use narrowly scoped, revocable API keys with quotas and server-side destination or account restrictions where supported.
  8. Add automated tests. Verify rejection of HTTP URLs, unknown domains, embedded URL credentials, unusual ports, malformed URLs, and redirects to untrusted origins.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (12)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation and command examples are entirely in Chinese, including prompts and translation targets, with no indication that users may choose another language or locale. This can violate language/locale policy when a skill implicitly enforces a specific language without opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation advertises image understanding with local file paths and URLs but does not warn that those images will be sent to a third-party remote API for processing. Users may unknowingly upload sensitive screenshots, documents, or personal images, creating a privacy and data-handling risk.

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 9)May include surrounding context.

md
const __dirname = fileURLToPath(new URL('.', import.meta.url));

const KIMI_API_KEY = process.env.KIMI_API_KEY;
const KIMI_API_HOST = process.env.KIMI_API_HOST || 'https://api.kimi.com/coding';
const MODEL = process.env.KIMI_MODEL || 'kimi-for-coding';
const VISION_MODEL = process.env.KIMI_VISION_MODEL || 'kimi-vl-flash';

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 62)May include surrounding context.

md
const __dirname = fileURLToPath(new URL('.', import.meta.url));

const KIMI_API_KEY = process.env.KIMI_API_KEY;
const KIMI_API_HOST = process.env.KIMI_API_HOST || 'https://api.kimi.com/coding';
const MODEL = process.env.KIMI_MODEL || 'kimi-for-coding';
const VISION_MODEL = process.env.KIMI_VISION_MODEL || 'kimi-vl-flash';

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/index.js (reported line 20)May include surrounding context.

js
const __dirname = fileURLToPath(new URL('.', import.meta.url));

const KIMI_API_KEY = process.env.KIMI_API_KEY;
const KIMI_API_HOST = process.env.KIMI_API_HOST || 'https://api.kimi.com/coding';
const MODEL = process.env.KIMI_MODEL || 'kimi-for-coding';
const VISION_MODEL = process.env.KIMI_VISION_MODEL || 'kimi-vl-flash';

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/index.js (reported line 160)May include surrounding context.

js
const __dirname = fileURLToPath(new URL('.', import.meta.url));

const KIMI_API_KEY = process.env.KIMI_API_KEY;
const KIMI_API_HOST = process.env.KIMI_API_HOST || 'https://api.kimi.com/coding';
const MODEL = process.env.KIMI_MODEL || 'kimi-for-coding';
const VISION_MODEL = process.env.KIMI_VISION_MODEL || 'kimi-vl-flash';

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The image command reads an arbitrary local file path and transmits the file contents as base64 to a remote API, but the CLI provides no explicit warning, confirmation, or privacy notice at the point of upload. In a skill/tooling context, this can cause users to unintentionally exfiltrate sensitive local images, screenshots, IDs, or proprietary documents to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill requires an API key and shows how to export it, but it does not warn users to protect the credential from logging, shell history exposure, commits, or sharing. This increases the chance of accidental credential leakage and unauthorized use of the external service.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The dependency uses a caret range instead of an exact pinned version, which makes builds non-reproducible and can silently pull in newer releases. This increases supply-chain risk because a compromised or breaking upstream publish could be installed without an intentional review.

Content

Scanner excerpt · package.json (reported line 11)May include surrounding context.

json
"kimi": "./scripts/index.js"
  },
  "dependencies": {
    "openai": "^4.0.0",
    "minimist": "^1.2.8"
  },
  "engines": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The minimist dependency is not pinned and is specified with a caret range, allowing different versions to be installed over time. Because minimist has a history of prototype-pollution advisories, leaving the resolved version unconstrained increases the chance of pulling an affected or otherwise risky release in different environments.

Content

Scanner excerpt · package.json (reported line 12)May include surrounding context.

json
},
  "dependencies": {
    "openai": "^4.0.0",
    "minimist": "^1.2.8"
  },
  "engines": {
    "node": ">=18.0.0"

Unverifiable Dependency: minimist has 2 known advisory(ies) (CVE-2020-7598 (Prototype Pollution in minimist); CVE-2021-44906 (Prototype Pollution in minimist)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
89% confidence
Finding

The manifest declares minimist without an exact version, and minimist has known prototype-pollution advisories in some releases. Without a pinned version or lockfile evidence, it is not possible to verify that deployments avoid vulnerable versions, which is relevant for a CLI tool that parses user-controlled arguments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The translate function sets the default target language to English, which imposes a locale choice when the caller does not specify --to. This is a natural-language policy concern because the skill forces a language preference by default rather than requiring user opt-in or clearly documenting a justified locale restriction.

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/index.js:19