Back to skill

Security audit

Yiliu

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real AI note-taking skill, but it can send private notes and search terms to a configurable AI endpoint and lacks some safety controls.

Install only if you are comfortable with note content and search terms being processed by the configured AI provider. Leave OPENAI_API_KEY unset for the most local behavior, keep OPENAI_BASE_URL on a trusted HTTPS provider, avoid storing highly sensitive secrets in notes, review dependency updates, and treat delete commands as irreversible.

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
src/ai/index.ts:13
Finding

Unvalidated custom AI endpoint can receive sensitive note content, search queries, and API credentials

Content
View full analysis

Vulnerability Details

File Location: src/ai/index.ts:13-16, 127-137, 211-221, 283-298, 332-347
Vulnerability Type: Unrestricted sensitive-data transmission to a configurable endpoint
Risk Level: Medium

Vulnerable Code

The destination and bearer credential are loaded directly from environment variables without validating the URL scheme, hostname, or resolved network address:

ts
const OPENAI_API_KEY = process.env.OPENAI_API_KEY || '';
const OPENAI_BASE_URL = process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1';
const EMBEDDING_MODEL = process.env.EMBEDDING_MODEL || 'text-embedding-3-small';
const CHAT_MODEL = process.env.CHAT_MODEL || 'gpt-4o-mini';

Individual note content is sent for embedding:

ts
const response = await fetch(`${OPENAI_BASE_URL}/embeddings`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${OPENAI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: EMBEDDING_MODEL,
    input: text.slice(0, 8000),
  }),
});

Batch input is transmitted in the same manner:

ts
const response = await fetch(`${OPENAI_BASE_URL}/embeddings`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${OPENAI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: EMBEDDING_MODEL,
    input: texts.map(t => t.slice(0, 8000)),
  }),
});

Note contents are also sent for automatic summaries and tags:

ts
const response = await fetch(`${OPENAI_BASE_URL}/chat/completions`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${OPENAI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: CHAT_MODEL,
    messages: [
      { role: 'system', content: systemPrompt },
      { role: 'user', content: content.slice(0, 4000) },
    ],
    temperature: 0.3,
    response_format: { type: 'json_object' },
  }),
});

Search queries are transmitted to the same configurable endpoint:

ts
con
...[truncated 3623 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse the configured endpoint with new URL() before making any request.
  2. Require https: and reject cleartext HTTP except for an explicitly enabled local-development mode.
  3. Use an allowlist of approved provider hostnames, with api.openai.com as the secure default.
  4. Resolve the hostname and reject loopback, link-local, private, multicast, and cloud metadata address ranges. Repeat validation after redirects or disable redirects.
  5. Require explicit configuration and a visible warning before allowing a non-default endpoint.
  6. Do not reuse OPENAI_API_KEY automatically for arbitrary OpenAI-compatible endpoints. Use endpoint-specific credential variables or credential records bound to an approved origin.
  7. Display the destination and data categories that will be transmitted, and obtain explicit consent before enabling cloud processing.
  8. Provide a clear local-only mode that prevents all cloud requests even when an API key exists.
  9. Consider separate controls for embedding, enhancement, and search-query expansion so users can minimize transmitted data.
  10. Add automated tests covering HTTP rejection, hostile domains, loopback addresses, private IP addresses, redirects to prohibited destinations, malformed URLs, and endpoint-specific credential binding.

A minimal validation pattern should resemble:

ts
function validateAIEndpoint(rawBaseUrl: string): URL {
  const endpoint = new URL(rawBaseUrl);

  if (endpoint.protocol !== 'https:') {
    throw new Error('AI endpoints must use HTTPS');
  }

  const allowedHosts = new Set(['api.openai.com']);
  if (!allowedHosts.has(endpoint.hostname)) {
    throw new Error('Unapproved AI endpoint');
  }

  return endpoint;
}

For deliberately supported third-party providers, maintain a separate allowlisted provider configuration and require credentials scoped specifically to that provider.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (52)

Known Vulnerable Dependency: protobufjs==6.11.4 — 11 advisory(ies): CVE-2026-44294 (protobuf.js: Denial of service from crafted field names in generated code); CVE-2026-44293 (protobuf.js: Code injection through bytes field defaults in generated toObject c); CVE-2026-44289 (protobuf.js: Denial of service through unbounded protobuf recursion) +8 more

Critical
Category
Supply Chain
Confidence
97% confidence
Finding

protobufjs 6.11.4 is present with numerous serious advisories, including denial of service and code-injection risks tied to parsing or generated code behavior. A dependency with this many critical issues is especially dangerous in a data-ingesting skill because imported content, sync payloads, or model artifacts may eventually touch protobuf processing paths.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: sharp==0.32.6 — 2 advisory(ies): GHSA-f88m-g3jw-g9cj (sharp inherited vulnerabilities in libvips: CVE-2026-33327, CVE-2026-33328, CVE-); GHSA-rgj7-g3m4-5g8c (sharp: Vulnerabilities in libheif: GHSA-g89c-p67h-r497 and GHSA-2jg2-4ch7-h545)

High
Category
Supply Chain
Confidence
95% confidence
Finding

sharp 0.32.6 is present with inherited image parsing issues from libvips/libheif, and image/media parsers are commonly exposed to attacker-controlled content. Given this skill handles note-taking and likely attachments or imported content, vulnerable image processing increases risk of denial of service or memory-safety issues via crafted files.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
92% confidence
Finding

form-data 4.0.5 is present and the advisory indicates CRLF injection through unescaped multipart field names or filenames. If any part names are derived from user-controlled note metadata or file names before outbound API calls, this could corrupt multipart requests or smuggle unexpected headers/content.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: langsmith==0.5.11 — 3 advisory(ies): CVE-2026-45134 (LangSmith SDK: Public prompt pull deserializes untrusted manifests without trust); CVE-2026-40190 (LangSmith Client SDKs has Prototype Pollution in langsmith-sdk via Incomplete `_); CVE-2026-41182 (LangSmith SDK: Streaming token events bypass output redaction)

High
Category
Supply Chain
Confidence
90% confidence
Finding

langsmith 0.5.11 is present with advisories including untrusted manifest deserialization, prototype pollution, and redaction bypass. In an AI-focused knowledge-base skill, telemetry/tracing SDK issues are more concerning because prompts, outputs, and plugin metadata may include sensitive note content and attacker-influenced data.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
94% confidence
Finding

ws 8.19.0 is present with advisories for uninitialized memory disclosure and memory-exhaustion DoS. Because this skill depends on LLM/database/network tooling that may use websocket transport, a vulnerable ws library can expose confidential data or allow remote service degradation through crafted websocket traffic.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger list contains many generic single-word activators such as '记', '搜', '找', '编辑', and '修改' that are likely to appear in ordinary conversation. This can cause accidental skill invocation or routing confusion, potentially exposing note-taking, search, export, or backup actions in contexts where the user did not intend to use this skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README explicitly promotes AI enhancement using an OpenAI API key but does not disclose that user note content may be sent to a third-party service for embeddings or summarization. In a note-taking knowledge base, notes may contain sensitive personal or organizational information, so missing this disclosure can lead users to unknowingly expose private data outside local storage expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README advertises OpenAI-backed AI features and API key configuration but does not clearly warn that note content may be transmitted to a third-party service when those features are enabled. In a note-taking knowledge-base context, users may store sensitive personal or proprietary information, so lack of disclosure can lead to unintended data exposure outside the local environment.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises network use and dependence on environment variables like OPENAI_API_KEY, but it does not declare an explicit tool/permission scope such as allowed-tools or permissions. That creates a transparency and policy-enforcement gap: a host may permit broader capabilities than users expect, and reviewers cannot easily verify or constrain what the skill is allowed to access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documented command interface uses Chinese-only slash commands such as /记, /搜, /列表, and /编辑 without stating that other languages are supported or that the user may choose their preferred locale. This is a natural-language policy concern because it imposes a specific language on users rather than offering an explicit language or locale choice.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The skill explicitly supports sending user note content to an external OpenAI-compatible endpoint for summaries, tags, and embeddings. Because this is a note-taking knowledge base, the transmitted data may contain sensitive personal, business, or credential-adjacent information; allowing a custom OPENAI_BASE_URL also increases the risk of accidental or malicious redirection to an untrusted endpoint.

Content

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

bash
export OPENAI_API_KEY="your-api-key"
# Optional: Custom API endpoint
export OPENAI_BASE_URL="https://api.openai.com/v1"

Without API Key: Falls back to local embeddings via @huggingface/transformers. Core features still work.

Abandoned Dependency: md5 is unmaintained and no longer receives security updates

Medium
Category
Supply Chain
Confidence
75% confidence
Finding

Dependency appears abandoned or unmaintained. Abandoned packages no longer receive security patches, leaving known and future vulnerabilities unaddressed.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The use-condition states only that the skill should be used when a user wants to record notes, search content, view history, or export data, but it does not define clear activation boundaries or disambiguation rules. Because these intents are common across many workflows, the ambiguity increases the chance of unintended activation and accidental access to potentially sensitive note, history, or export functionality.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · README.md (reported line 99)May include surrounding context.

md
// OpenAI API 配置
const OPENAI_API_KEY = process.env.OPENAI_API_KEY || '';
const OPENAI_BASE_URL = process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1';
const EMBEDDING_MODEL = process.env.EMBEDDING_MODEL || 'text-embedding-3-small';
const CHAT_MODEL = process.env.CHAT_MODEL || 'gpt-4o-mini';

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · README_CN.md (reported line 99)May include surrounding context.

md
// OpenAI API 配置
const OPENAI_API_KEY = process.env.OPENAI_API_KEY || '';
const OPENAI_BASE_URL = process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1';
const EMBEDDING_MODEL = process.env.EMBEDDING_MODEL || 'text-embedding-3-small';
const CHAT_MODEL = process.env.CHAT_MODEL || 'gpt-4o-mini';

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · src/ai/index.ts (reported line 14)May include surrounding context.

ts
// OpenAI API 配置
const OPENAI_API_KEY = process.env.OPENAI_API_KEY || '';
const OPENAI_BASE_URL = process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1';
const EMBEDDING_MODEL = process.env.EMBEDDING_MODEL || 'text-embedding-3-small';
const CHAT_MODEL = process.env.CHAT_MODEL || 'gpt-4o-mini';

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code sends note content to a remote OpenAI chat-completions endpoint for summarization without any visible consent gate, warning, or data-classification check in this module. Because notes may contain sensitive personal or business information, this creates a real privacy and data-handling risk through third-party transmission.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

User-provided note text is intentionally transmitted to a third-party AI provider for summarization, tag extraction, and keyword extraction. In a note-taking knowledge-base skill, the content is especially likely to include sensitive or proprietary data, making external plain-language processing materially risky if users are not clearly informed and protected.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The function forwards raw user search queries to a remote AI service for query expansion with no user-facing disclosure or consent mechanism in this file. Search queries can reveal sensitive interests, internal project names, credentials pasted by mistake, or other private context, so undisclosed external transmission is a legitimate privacy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module's natural-language strings are entirely in Chinese and multiple timestamps are explicitly formatted with toLocaleString('zh-CN'). This enforces a specific language/locale choice without any visible user opt-in or configuration path in the file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The delete handler immediately performs irreversible note deletion based only on an ID and returns success or failure, with no confirmation step, soft-delete, or undo safeguard. In an agent or chat-driven interface, ambiguous references, accidental invocation, or prompt/UI confusion can cause unintended destruction of user data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

User-facing strings, commands, and help text are entirely in Chinese, and the trigger surface is centered on Chinese keywords such as 记, 搜索, and 删除, with no indication that other languages are supported or that the user can opt into this locale. The policy check for natural-language issues applies to all file types and flags language constraints that are imposed without user choice or clear justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The /删除 command directly invokes note.handleDelete(arg) with no visible confirmation, preview, or undo requirement in this entrypoint. In a conversational agent, accidental triggering, ambiguous IDs/keywords, or prompt-influenced actions can lead to irreversible loss of user data.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The handler automatically detects any message containing an HTTP(S) URL and passes the full message to note.handleLinkCapture, which expands behavior beyond the declared note-taking/search/versioning scope. This can cause unexpected retrieval or processing of external content, potentially exposing internal network resources, leaking metadata, or surprising users who intended only to store text containing a URL.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Note content is automatically sent through AI processing via generateEmbedding and enhanceNote when AI is available, with no indication in this module that the user explicitly consented to external processing. In a note-taking context, stored notes may contain highly sensitive personal or business data, so silent AI processing can create a privacy and data-governance risk, especially if the AI backend is remote.

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
src/ai/index.ts:13