Back to skill

Security audit

RAG Retriever V3

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real RAG retrieval tool, but it can unexpectedly send document text to cloud embedding services and has weak safeguards around retrieved content.

Install only if you are comfortable managing a RAG database that stores indexed document text locally. For sensitive documents, explicitly configure the local Xenova provider, avoid relying on auto mode, and ensure OPENAI_API_KEY is not present unless cloud embedding upload is intended. Pin or prefetch model artifacts, update vulnerable dependencies, and do not feed generated RAG prompts directly to tool-using agents without prompt-injection controls.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (3)

T01 · Skill Instruction Hijacking

Error
Location
src/core/CitationManager.js:101
Finding

Untrusted retrieved documents are inserted into downstream AI prompts without prompt-injection isolation

Content
View full analysis

Vulnerability Details

File Location: src/core/CitationManager.js:101-105 and src/core/CitationManager.js:158-175
Vulnerability Type: Indirect prompt injection
Risk Level: High

Complete Code Snippet

javascript
const contextParts = results.map((result, index) => {
  const citation = result.citation || this.addCitations(
    [result],
    { startIndex: index + 1 }
  )[0].citation;
  const content = citation.content || result.content || result.text || '';

  if (includeCitations) {
    return `${citation.mark} ${content}`;
  } else {
    return content;
  }
});
javascript
generateRAGPrompt(query, results, options = {}) {
  const systemPrompt = options.systemPrompt || this.getDefaultSystemPrompt();
  const context = this.generateContext(results, options);
  const citationList = this.generateCitationList(results);

  const fullPrompt = `${systemPrompt}

用户问题:${query}

参考信息:
${context}

请基于以上参考信息回答用户问题。如果参考信息不足以回答问题,请明确说明。

---
来源引用:
${citationList}`;

  return {
    query,
    context,
    citationList,
    fullPrompt,
    citations: results.map(r => r.citation),
    resultCount: results.length
  };
}

Technical Analysis

Document content is treated as trusted prompt text after retrieval. generateContext() concatenates each retrieved chunk directly into a string, and generateRAGPrompt() subsequently places that string in the same natural-language prompt as the system guidance and user question.

There is no structural separation identifying retrieved passages as untrusted data, no escaping or encoding, no filtering of instruction-like content, and no explicit rule requiring the downstream model to ignore commands found inside reference documents. Citation prefixes such as [1] provide provenance but do not establish a security boundary.

Consequently, an indexed document can contain instructions aimed at the downstream model, for example c ...[truncated 1570 chars]

Remediation
View remediation

Remediation Suggestions

  1. Treat all retrieved documents and metadata as untrusted input.
  2. Add an explicit instruction before the context stating that content inside retrieved passages is data only and that any commands, role declarations, or policy changes inside it must be ignored.
  3. Use strong, unique boundaries or a structured message format rather than concatenating system instructions, user input, and retrieved data into one natural-language string.
  4. Encode each passage as a structured object containing an identifier, source, and content field.
  5. Detect and flag instruction-like passages, including role changes, requests to ignore prior instructions, requests for secrets, and tool-use directives.
  6. Ensure the downstream integration sends trusted policy through a system-level message and retrieved passages through a lower-trust data channel.
  7. Require confirmation or additional policy checks before a downstream Agent performs tool operations based on retrieved content.
  8. Add adversarial tests containing prompt-injection text in indexed documents and verify that the consuming model treats it only as quoted reference material.

T09 · Insecure Skill Coding Practices

Warning
Location
src/embeddings/index.js:52
Finding

Ambient API key presence silently changes local document processing to external cloud transmission

Content
View full analysis

Vulnerability Details

File Location: src/cli.js:25-29, src/embeddings/index.js:52-56, src/core/RAGRetrieverV3.js:128-130, and src/embeddings/OpenAIEmbedding.js:112-117
Vulnerability Type: Unintended sensitive-data disclosure through insecure provider selection
Risk Level: Medium

Complete Code Snippet

javascript
const rag = new RAGRetrieverV3({
  dbPath: config.dbPath || './data/lancedb-v3',
  embeddingProvider: config.embeddingProvider || 'auto',
  ...config
});
javascript
case 'auto':
  if (process.env.OPENAI_API_KEY && OpenAIEmbedding) {
    console.log('[EmbeddingFactory] 检测到 OPENAI_API_KEY,使用 OpenAI 嵌入');
    return new OpenAIEmbedding(options);
  } else {
    if (process.env.OPENAI_API_KEY && !OpenAIEmbedding) {
      console.log('[EmbeddingFactory] ⚠️ 检测到 OPENAI_API_KEY 但 openai 模块未安装');
      console.log('[EmbeddingFactory] 使用本地 Xenova 嵌入(运行: npm install openai 以启用 OpenAI)');
    } else {
      console.log('[EmbeddingFactory] 未检测到 API Key,使用本地 Xenova 嵌入');
    }
    return new XenovaEmbedding(options);
  }
javascript
const embeddings = await this.embedding.embedBatch(
  chunks.map(c => c.content)
);
javascript
const response = await this.client.embeddings.create({
  model: this.modelName,
  input: batch,
  encoding_format: 'float'
});

Technical Analysis

The CLI defaults to the auto embedding provider. In this mode, the presence of OPENAI_API_KEY in the process environment automatically selects the OpenAI provider. Document chunks passed to addDocument() are then sent as the input field of an external embedding API request.

This behavior relies on ambient environment state rather than explicit authorization to transmit a particular document. Environments commonly expose API keys globally through shell profiles, secret managers, containers, or CI configuration. An operator may therefo ...[truncated 1663 chars]

Remediation
View remediation

Remediation Suggestions

  1. Make the local Xenova provider the unconditional default.
  2. Require explicit configuration such as embeddingProvider: "openai" before transmitting document text.
  3. Do not infer consent from the mere presence of OPENAI_API_KEY.
  4. Display the target hostname and a clear data-transfer warning before the CLI uploads document chunks.
  5. Require interactive confirmation for cloud processing, with a separate non-interactive opt-in flag for automated deployments.
  6. Validate baseURL using the URL parser, require HTTPS, and use an allowlist of approved hosts unless the operator explicitly enables custom endpoints.
  7. Never send the OpenAI credential to a custom endpoint without a distinct, explicit configuration setting.
  8. Add configuration options for redaction, data classification, maximum transmitted size, and cloud processing prohibition.
  9. Document exactly which fields are sent externally and add tests proving that auto or default operation remains local.

T08 · Insecure Dependencies

Note
Location
src/embeddings/XenovaEmbedding.js:10
Finding

Remote embedding and reranking models are loaded from mutable revisions without integrity pinning

Content
View full analysis

Vulnerability Details

File Location: src/embeddings/XenovaEmbedding.js:10-11 and src/embeddings/XenovaEmbedding.js:52-64; equivalent behavior is present in src/rerank/CrossEncoderReranker.js:10-11 and src/rerank/CrossEncoderReranker.js:42-54
Vulnerability Type: Mutable remote model supply-chain dependency
Risk Level: Low

Complete Code Snippet

javascript
env.allowLocalModels = true;
env.allowRemoteModels = true;
javascript
this.pipeline = await pipeline(
  'feature-extraction',
  this.modelName,
  {
    quantized: true,
    revision: 'main',
    progress_callback: (progress) => {
      if (progress.status === 'progress') {
        const percent = (
          (progress.loaded / progress.total) * 100
        ).toFixed(1);
        process.stdout.write(
          `\r[XenovaEmbedding] 加载进度: ${percent}%`
        );
      }
    }
  }
);
javascript
this.pipeline = await pipeline(
  'text-classification',
  this.modelName,
  {
    revision: 'main',
    progress_callback: (progress) => {
      if (progress.status === 'progress') {
        const percent = (
          (progress.loaded / progress.total) * 100
        ).toFixed(1);
        process.stdout.write(
          `\r[CrossEncoderReranker] 加载进度: ${percent}%`
        );
      }
    }
  }
);

Technical Analysis

Both model-loading components enable remote models and request the mutable main revision. The model identifier is configurable, and the implementation does not enforce an allowlist, pin an immutable repository commit, or verify an independently maintained checksum.

As a result, a model that was reviewed at one point can resolve to different artifacts later. A compromised upstream account, repository, distribution service, or configuration file could cause an altered tokenizer, configuration, or ONNX model to be downloaded during initialization.

The ...[truncated 1498 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin each approved model to an immutable repository commit rather than main.
  2. Maintain an allowlist of model identifiers and expected revisions.
  3. Verify downloaded artifacts against independently recorded cryptographic hashes.
  4. Reject arbitrary model names supplied through untrusted configuration.
  5. Pre-download and review models during a controlled build process, then disable remote model loading in production.
  6. Use a trusted internal model mirror where appropriate.
  7. Apply download-size, storage, memory, and inference-time limits to reduce denial-of-service exposure.
  8. Record the resolved model revision and artifact hashes in logs and statistics for reproducibility.
  9. Add tests that fail when a model is configured with a mutable revision.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (45)

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 flagged with multiple serious advisories including denial of service and possible code-generation/injection issues. Even though this lockfile alone does not show active exploitation, shipping a package tree with a critically vulnerable serialization library is dangerous because crafted protobuf data or schema content can crash processing or, in code-generation workflows, lead to unsafe code emission.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/cli.js init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/cli.js init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/cli.js init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/cli.js init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/cli.js init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/cli.js init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
import { CitationManager } from './src/core/CitationManager.js';

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
95% confidence
Finding

form-data 4.0.5 is a known vulnerable version for CRLF injection in multipart field names. This project transitively includes it through the OpenAI client stack, so if attacker-controlled field names or filenames ever reach multipart construction, requests could be malformed or manipulated, potentially enabling header injection or request smuggling against upstream services.

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
92% confidence
Finding

sharp 0.32.6 is reported as inheriting vulnerabilities from bundled image-processing libraries such as libvips/libheif. In an AI/retrieval toolchain that may ingest external images or model assets, malformed image files could trigger crashes, memory corruption, or denial of service in native code, making this materially risky despite being a transitive dependency.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This manifest uses Chinese throughout the file, including headings and descriptions, but does not state that the skill is Chinese-only or provide any language/locale choice. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation unless clearly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README describes the skill entirely in Chinese and explicitly highlights '中文优化' as a core feature, but it does not state that the skill is region-specific or provide any language/locale opt-in. This can violate language/locale policy because it implies a fixed language experience without user choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly documents an OpenAI embedding provider but does not warn that input documents and queries may be transmitted to a third-party cloud API. In a RAG system, document ingestion often includes proprietary or sensitive content, so omission of this disclosure can lead to unintended external data exposure and policy/compliance violations.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The documented configuration includes a default OpenAI API endpoint, which indicates the skill supports transmission of user-supplied content to an external service. In the context of a retriever that processes full documents, this can expose sensitive internal text outside the local environment if users enable the cloud embedding path without understanding the implications.

Content

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

md
modelName: 'Xenova/all-MiniLM-L6-v2',
    // OpenAI 选项
    apiKey: process.env.OPENAI_API_KEY,
    baseURL: 'https://api.openai.com/v1'
  },
  
  // 分块配置

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This file presents its interface and help text exclusively in Chinese, including the header comment and command output/help content. That can violate a language/locale policy when the skill forces a specific language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language comments describe the strategy as '文档分块策略' and '针对中文优化', which indicates a Chinese-specific language/locale bias. Under the policy, forcing or implying a specific language/locale without user opt-in or clear justified regional scope is a violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The default prompt is written entirely in Chinese and instructs the assistant how to answer, which effectively imposes a specific language/locale behavior by default. There is no indication here that the user can choose the response language or that the Chinese-only behavior is limited to a justified region-specific context.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The retriever class exposes destructive database administration functionality via dropCollection(), which is outside its stated retrieval-focused responsibility. In an agent/skill context, this broadens the attack surface: any caller that can reach the retriever may be able to delete tables, causing data loss or disruption without separate authorization boundaries.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

dropCollection(name) performs irreversible deletion immediately with no confirmation, safety interlock, or validation of the requested collection name. In systems where an LLM agent or loosely trusted caller can invoke this method, a mistaken or manipulated call could wipe knowledge-base data and impair service availability.

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 · src/embeddings/OpenAIEmbedding.js (reported line 27)May include surrounding context.

js
super(options);
    this.apiKey = options.apiKey || process.env.OPENAI_API_KEY;
    this.modelName = options.modelName || 'text-embedding-3-small';
    this.baseURL = options.baseURL || 'https://api.openai.com/v1';
    this.name = 'openai';
    this.client = null;

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file claims the embedding model runs locally and needs no API key, but it also sets env.allowRemoteModels = true, which permits fetching model artifacts from remote sources. This discrepancy can mislead operators into assuming strictly local behavior, weakening deployment trust boundaries and potentially introducing unreviewed third-party model code/assets into the environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code file enables remote models via env.allowRemoteModels = true, and later initializes a pipeline with the selected model name. Although there are console logs for model loading progress, there is no explicit user disclosure that model fetching may involve network access and could transmit usage metadata or model selection off the machine, which is relevant because the class is described as a local embedding model.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file contains user-facing natural-language strings exclusively in Chinese, including error and console output. That enforces a specific language/locale without any visible opt-in or fallback, which is a natural-language policy concern under the stated rules.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code enables remote models and then sends query-document pairs to the pipeline for inference. Although the file logs model-loading and progress, it does not clearly disclose in comments or user-facing messaging that model loading/inference may involve network access and transmission of user-provided text.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The manifest description uses Chinese-language text exclusively, which may impose a language preference without offering user opt-in or documenting that the skill is intended only for a Chinese-speaking or region-specific audience. Under the policy, language constraints should be optional or explicitly justified.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
test/run-all-tests.js:22