Back to skill

Security audit

Vector DB Toolkit

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent vector database toolkit, with expected but security-relevant network, persistence, and deletion behaviors that users should configure carefully.

Use a virtual environment and consider pinning or locking dependencies before installation. Test against non-production vector collections first, be careful that delete without IDs removes an entire collection, and only use the OpenAI embedding provider for text you are allowed to send to an external service.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned Third-Party Dependencies Permit Unreviewed Package Upgrades

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-5
Related Installation Instruction: README.md:13-17
Vulnerability Type: Third-party supply-chain exposure through unbounded dependency versions
Risk Level: Medium

Vulnerable Code

text
qdrant-client>=1.7.0
chromadb>=0.4.18
numpy>=1.24.0
requests>=2.31.0
sentence-transformers>=2.2.2

The documented installation command is:

bash
pip install -r requirements.txt

Technical Analysis

Every dependency uses only a minimum-version constraint. Consequently, installation may resolve to any later package release, including versions that were not reviewed or tested with this project. The installation is also not protected by package hashes or a committed lock file.

Python package installation can execute package build and installation logic with the privileges of the user running pip. If an upstream project, release account, distribution artifact, or configured package index is compromised, a malicious later release could be selected without any modification to this repository.

There is no evidence that the listed package names are typosquatted or currently malicious. The vulnerability is the absence of reproducible, integrity-verified dependency resolution rather than a confirmed malicious dependency.

Attack Path

  1. An attacker compromises an upstream dependency release, its publishing credentials, or a package index used by the victim.
  2. The attacker publishes a malicious version greater than the minimum version accepted by requirements.txt.
  3. A user follows the documented pip install -r requirements.txt instruction.
  4. The resolver selects the compromised release because no upper bound, exact version, lock file, or hash prevents it.
  5. Malicious package installation or import-time code executes in the user's environment.

Impact Assessment

Exploitation could run arbitrary code ...[truncated 584 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin each direct and transitive dependency to a reviewed exact version using a lock file.
  2. Generate and verify cryptographic hashes, such as with pip-compile --generate-hashes, and install with pip install --require-hashes.
  3. Use a trusted, explicitly configured package index or an internally mirrored repository.
  4. Separate optional dependency groups for Qdrant, Chroma, OpenAI requests, and local sentence-transformer support so users install only what they need.
  5. Add automated dependency vulnerability and provenance scanning to CI.
  6. Test dependency upgrades separately and update the lock file only after review.
  7. Avoid running package installation as root or another privileged account.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/embedding_utils.py:29
Finding

Optional OpenAI Embedding Provider Transmits Arbitrary Caller Text Without Adequate Data-Boundary Safeguards

Content
View full analysis

Vulnerability Details

File Location: scripts/embedding_utils.py:29-43
Vulnerability Type: Insufficiently disclosed external transmission of potentially sensitive input
Risk Level: Medium

Vulnerable Code

python
    def _openai_encode(self, texts: List[str]) -> List[List[float]]:
        import os, requests
        api_key = os.environ.get("OPENAI_API_KEY")
        if not api_key:
            raise RuntimeError("OPENAI_API_KEY not set")
        resp = requests.post(
            "https://api.openai.com/v1/embeddings",
            headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
            json={"model": self.model_name or "text-embedding-ada-002", "input": texts},
        )
        resp.raise_for_status()
        data = resp.json()["data"]
        return [d["embedding"] for d in data]

Technical Analysis

When the caller explicitly selects provider="openai", the implementation sends every string in texts to the fixed OpenAI embeddings endpoint. RAG and semantic-search inputs frequently contain private documents, personal information, internal source material, access tokens, or other secrets.

External transmission is functionally necessary for this optional provider, and the request uses HTTPS. The API key is used as an authorization credential for the intended endpoint; there is no evidence of credential theft, hidden destinations, or malicious exfiltration. However, the project documentation only describes OpenAI as an optional embedding helper and does not clearly identify the resulting external data boundary or warn users that raw input text leaves the local environment.

The implementation also provides no redaction, content classification, size limit, policy callback, or explicit per-request confirmation. The request has no timeout, allowing a remote service or network failure to block the invoking workflow indefinitely.

Attack Pat

...[truncated 1411 chars]

Remediation
View remediation

Remediation Suggestions

  1. Prominently document that selecting the OpenAI provider sends raw caller-supplied text to an external service.
  2. Require explicit remote-processing consent or configuration rather than relying only on the provider string.
  3. Keep local embedding as the default and fail closed when remote processing has not been expressly authorized.
  4. Add a configurable data-policy callback that can reject, redact, or tokenize sensitive content before transmission.
  5. Warn users not to submit secrets, regulated data, or confidential documents unless organizational policy permits it.
  6. Add a bounded timeout, for example:
    python
    resp = requests.post(
        "https://api.openai.com/v1/embeddings",
        headers=headers,
        json=payload,
        timeout=(5, 60),
    )
    
  7. Add configurable request-size and batch-size limits.
  8. Test that remote transmission occurs only for the explicitly selected OpenAI provider and that timeout and redaction controls are enforced.
  9. Avoid logging request headers, API keys, or raw text when adding diagnostics.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (23)

Tainted flow: 'api_key' from os.environ.get (line 32, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/embedding_utils.py (reported line 35)May include surrounding context.

python
api_key = os.environ.get("OPENAI_API_KEY")
        if not api_key:
            raise RuntimeError("OPENAI_API_KEY not set")
        resp = requests.post(
            "https://api.openai.com/v1/embeddings",
            headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
            json={"model": self.model_name or "text-embedding-ada-002", "input": texts},

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared purpose is vector database management, but the analyzed behavior reportedly centers on embedding generation and undeclared external calls to the OpenAI embeddings API, while lacking the promised Qdrant/Chroma/in-memory operations. This mismatch is dangerous because it can mislead operators into approving a local datastore skill that actually sends data off-box to third parties, creating confidentiality, compliance, and trust-boundary violations.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises code-backed vector database functionality but declares no explicit tool scope or permissions despite requiring network and environment access. This is dangerous because agents may invoke the skill without clear user-visible boundaries, enabling unexpected outbound connections or secret usage during routine RAG/database tasks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

When a host is provided, the code initializes a remote HTTP client, which means later vector, metadata, and query data may be sent over the network. This file contains no confirmation prompt, logging, or comment/docstring warning users that data can be transmitted to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The delete method can remove specific records or delete an entire collection when ids is not provided. Although deletion is part of the method's purpose, there is no warning, confirmation, or explanatory comment/docstring indicating that omitting ids deletes the whole collection.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

When provider='openai', arbitrary input texts are transmitted to a third-party service without any in-code notice, consent gate, or data-classification check. In a RAG/vector toolkit, inputs may contain sensitive prompts, documents, secrets, or customer data, so silent external transmission can create privacy, compliance, and data-handling risks.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

This code performs external transmission of user-supplied text to the OpenAI embeddings API. In the context of a vector/RAG toolkit, that is functional behavior, but it is still security-relevant because embedding inputs often contain proprietary or sensitive content and the transfer occurs automatically when the remote provider is selected.

Content

Scanner excerpt · scripts/embedding_utils.py (reported line 35)May include surrounding context.

python
api_key = os.environ.get("OPENAI_API_KEY")
        if not api_key:
            raise RuntimeError("OPENAI_API_KEY not set")
        resp = requests.post(
            "https://api.openai.com/v1/embeddings",
            headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
            json={"model": self.model_name or "text-embedding-ada-002", "input": texts},

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

This code performs external transmission of user-supplied text to the OpenAI embeddings API. In the context of a vector/RAG toolkit, that is functional behavior, but it is still security-relevant because embedding inputs often contain proprietary or sensitive content and the transfer occurs automatically when the remote provider is selected.

Content

Scanner excerpt · scripts/embedding_utils.py (reported line 35)May include surrounding context.

python
api_key = os.environ.get("OPENAI_API_KEY")
        if not api_key:
            raise RuntimeError("OPENAI_API_KEY not set")
        resp = requests.post(
            "https://api.openai.com/v1/embeddings",
            headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
            json={"model": self.model_name or "text-embedding-ada-002", "input": texts},

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/embedding_utils.py (reported line 36)May include surrounding context.

python
if not api_key:
            raise RuntimeError("OPENAI_API_KEY not set")
        resp = requests.post(
            "https://api.openai.com/v1/embeddings",
            headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
            json={"model": self.model_name or "text-embedding-ada-002", "input": texts},
        )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The delete method can remove selected points or an entire collection, including the irreversible delete_collection path when no IDs are provided. There is no confirmation prompt, logging, comment, or docstring warning users that this method performs destructive deletion.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This markdown file includes example operations that create a collection and upsert payload data into a vector database, which can affect persisted user or system data. The README does not provide any warning or note that these commands modify the target backend, so users may run them without realizing they are performing write operations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The markdown shows example commands that create a collection and upsert payload data into a vector database, which modify persisted data, but the skill description does not include any caution about changing local or remote database contents. For a markdown file, this fits missing user warnings because the documented behavior can affect user data and system state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

This markdown file includes deletion operations for an entire collection and individual points, but the surrounding documentation does not warn users about the destructive nature of these actions. For markdown files, SQP-2 applies when descriptions omit warnings about behaviors that could affect user data or system integrity.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified with a lower-bound range only, so builds may resolve to different versions over time, including versions later found to be vulnerable or incompatible. In a security-sensitive vector database toolkit, this weakens supply-chain control and makes vulnerability triage and reproducibility difficult.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
qdrant-client>=1.7.0
chromadb>=0.4.18
numpy>=1.24.0
requests>=2.31.0

Unverifiable Dependency: qdrant-client has 2 known advisory(ies) (CVE-2024-3829 (qdrant input validation failure ); CVE-2024-3829 (qdrant input validation failure )), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The manifest does not pin qdrant-client, so it is impossible to verify whether the installed version includes or avoids the cited advisory. In a vector database toolkit, this uncertainty matters because the client mediates access to remote data stores and may expose applications to known flaws if an affected version is resolved.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

chromadb is unpinned, meaning installation may pull different releases at different times, including releases with serious security defects. Because this toolkit directly supports vector stores used in RAG pipelines, a vulnerable ChromaDB version could expose stored embeddings, documents, or enable code-execution paths depending on the affected release.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
qdrant-client>=1.7.0
chromadb>=0.4.18
numpy>=1.24.0
requests>=2.31.0
sentence-transformers>=2.2.2

Unverifiable Dependency: chromadb has 8 known advisory(ies) (CVE-2026-45830 (ChromaDB allows any authenticated users to arbitrarily read, write, update, or d); CVE-2026-45833 (ChromaDB has a code injection vulnerability); CVE-2026-45829 (ChromaDB Python project has a pre-authentication code injection vulnerability) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The unpinned chromadb dependency cannot be validated against multiple known advisories, including severe issues such as arbitrary access and code injection in some releases. This is especially dangerous in a vector store/RAG context because ChromaDB may hold sensitive embeddings and source documents, and a vulnerable release could enable data compromise or code execution.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Using numpy with only a minimum version does not guarantee a safe or reproducible version will be installed. While NumPy is often lower-risk in this context than network-facing components, unpinned scientific dependencies still create supply-chain uncertainty and may introduce vulnerable or unstable builds.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
qdrant-client>=1.7.0
chromadb>=0.4.18
numpy>=1.24.0
requests>=2.31.0
sentence-transformers>=2.2.2

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
83% confidence
Finding

Because numpy is unpinned, the project cannot demonstrate that installed versions are free from known advisories. Although the practical exposure in this toolkit may be lower than for networked services, the inability to verify dependency safety is still a real supply-chain weakness.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

requests is unpinned, so deployments can silently consume different versions with different security properties, including versions affected by credential leakage or TLS-related flaws. Since this toolkit may connect to remote vector databases or model endpoints, a vulnerable HTTP client raises the risk of data exposure during network operations.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
qdrant-client>=1.7.0
chromadb>=0.4.18
numpy>=1.24.0
requests>=2.31.0
sentence-transformers>=2.2.2

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The requests package has known advisories, but the loose version specifier prevents determining whether deployments are safe. Given that this toolkit may communicate with remote services, an affected requests version could contribute to credential leakage, mishandled redirects, or other network-layer security issues.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

sentence-transformers is unpinned, which makes installs non-deterministic and increases exposure to future vulnerable or compromised releases. In an embedding/RAG toolkit this package may process untrusted text and pull transitive ML dependencies, so version drift broadens supply-chain risk.

Content

Scanner excerpt · requirements.txt (reported line 5)May include surrounding context.

text
chromadb>=0.4.18
numpy>=1.24.0
requests>=2.31.0
sentence-transformers>=2.2.2

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This wrapper initializes an HTTP client with an optional API key and subsequently sends vectors and payload data to a remote Qdrant service via upsert and search operations. The file contains no docstring, comments, logging, or other user-facing disclosure that data may be transmitted over the network to an external service.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.