Back to skill

Security audit

LiteRAG

Security checks for vulnerabilities and agentic risk

Overview

This documentation-search skill is coherent, but a workspace config can make it read broad local paths and send indexed text, queries, and bearer tokens to any configured embedding endpoint.

Review the workspace .literag/knowledge-libs.json before indexing. Only use source paths you intend to store and search, avoid broad home-directory or credential-containing paths, and keep embeddings on a trusted local endpoint unless you explicitly accept sending document text, queries, and the configured bearer token to a remote provider. Pin or review sqlite-vec before production use.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/literag_common.py:642
Finding

Configurable Embedding Endpoint Can Expose Document Contents, Search Queries, and Bearer Credentials

Content
View full analysis

Vulnerability Details

File Location: scripts/literag_common.py:125-196, scripts/literag_common.py:642-666, scripts/literag_common.py:826-831, scripts/literag_common.py:848-866, scripts/literag_common.py:1059-1061
Vulnerability Type: Unrestricted transmission of potentially sensitive data to a configurable network endpoint
Risk Level: Medium

Vulnerable Code

Configuration permits arbitrary source paths and an arbitrary embedding endpoint:

python
def load_config(config_path: str | Path) -> AppConfig:
    config_path = Path(config_path).expanduser().resolve()
    workspace_root = detect_workspace_root(config_path)
    raw = json.loads(config_path.read_text(encoding="utf-8"))
    defaults = raw.get("defaults", {})
    chunking = defaults.get("chunking", {})
    retrieval = defaults.get("retrieval", {})
    fts = retrieval.get("fts", {})
    vector = retrieval.get("vector", {})
    hybrid = retrieval.get("hybrid", {})
    ranking = defaults.get("ranking", raw.get("ranking", {}))
    embedding = raw.get("embedding", {})

    libraries = []
    for lib in raw.get("libraries", []):
        lib_chunking = lib.get("chunking", {})
        lib_retrieval = lib.get("retrieval", {})
        lib_vector = lib_retrieval.get("vector", {})
        lib_hybrid = lib_retrieval.get("hybrid", {})
        lib_ranking = lib.get("ranking", {})
        source_paths = []
        for source in lib.get("paths", []):
            source_paths.append(
                {
                    "path": str(resolve_path(source["path"], base_dir=config_path.parent)),
                    "include": source.get("include") or ["**/*"],
                    "exclude": source.get("exclude") or [],
                }
            )
        libraries.append(
            LibraryConfig(
                id=lib["id"],
                name=lib.get("name", lib["id"]),
                sqlite_path=resolve_path(

...[truncated 10217 chars]
Remediation
View remediation

Remediation Suggestions

  1. Restrict embedding endpoints to loopback addresses by default.
  2. Require an explicit configuration flag such as allowRemoteEmbeddingEndpoint before contacting non-loopback hosts.
  3. Reject non-HTTP(S) schemes, URL user information, malformed hosts, and remote plaintext HTTP endpoints.
  4. Require HTTPS for every non-loopback endpoint and perform normal certificate validation.
  5. Display the destination origin and request confirmation before the first remote transmission.
  6. Clearly document that vector indexing sends corpus text and vector/hybrid search sends query text to the configured provider.
  7. Support a destination allowlist or administrator policy enforced independently of the workspace configuration.
  8. Restrict source paths to approved roots unless the user explicitly authorizes an external path.
  9. Add default exclusions for .env, private keys, credential stores, VCS metadata, cloud credentials, and similar sensitive files.
  10. Add a dry-run mode that lists selected files and the embedding destination before network transmission.
  11. Avoid sending bearer credentials over plaintext transport and redact credentials from all diagnostics.
  12. Preserve and prominently document FTS-only operation as a network-free alternative.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Native SQLite Dependency Is Not Reproducibly Pinned or Integrity-Verified

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1, SKILL.md:16-20, skill.json:18-26, scripts/literag_common.py:398-415
Vulnerability Type: Unpinned native dependency and missing package-integrity verification
Risk Level: Low

Vulnerable Code

The dependency declaration accepts any future release at or above the specified minimum version:

text
sqlite-vec>=0.1.9

The documented installation command resolves the dependency without hashes:

bash
python3 -m pip install -r {baseDir}/requirements.txt

Package metadata repeats the same unconstrained dependency:

json
"install": {
  "type": "pip",
  "command": "pip install -r requirements.txt",
  "packages": [
    "sqlite-vec>=0.1.9"
  ],
  "source": "pypi"
}

The installed package is imported and used to load a native SQLite extension:

python
try:
    import sqlite_vec as _sqlite_vec_module
except Exception:
    _sqlite_vec_module = None
python
def load_sqlite_vec(conn: sqlite3.Connection) -> bool:
    if not sqlite_vec_available(conn):
        return False
    try:
        conn.enable_load_extension(True)
        _sqlite_vec_module.load(conn)
        conn.enable_load_extension(False)
        return True
    except Exception:
        try:
            conn.enable_load_extension(False)
        except Exception:
            pass
        return False

Technical Analysis

The version constraint sqlite-vec>=0.1.9 does not produce a reproducible dependency set. Every installation may resolve a different future release, and the installation workflow does not use package hashes to verify the exact downloaded artifacts.

This is more security-sensitive than an unpinned pure-Python utility because the dependency is imported into the Skill process and loads a native SQLite extension. Code in a compromised package release can execute during installation, import ...[truncated 1641 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin sqlite-vec to an explicitly reviewed version rather than using a lower-bound-only constraint.
  2. Generate platform-appropriate lock files containing cryptographic hashes.
  3. Install with pip --require-hashes in production or packaged deployments.
  4. Review release notes, provenance, signatures, and binary artifacts before upgrading the pinned version.
  5. Use a trusted internal package mirror where operationally appropriate.
  6. Run dependency vulnerability and provenance checks in continuous integration.
  7. Install and run the Skill under a nonprivileged account.
  8. Consider making sqlite-vec optional and retaining the existing Python-side vector fallback when the native extension is unavailable.
  9. Ensure SQLite extension loading is enabled only for the duration of loading the expected module, as the current implementation attempts to do.
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (10)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill is explicitly user-invocable and documents capabilities that imply shell execution, file reads, environment-based workspace resolution, package installation, and possible network access, yet it declares no explicit tool scope or permissions boundary. In an agent ecosystem, this creates an authorization ambiguity: the runtime may grant broader capabilities than users or reviewers expect, increasing the risk of unintended command execution, workspace-wide file access, or external dependency fetching.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/benchmark_library.py (reported line 40)May include surrounding context.

python
"--no-text",
    ]
    started = time.perf_counter()
    proc = subprocess.run(cmd, capture_output=True, text=True)
    elapsed_ms = (time.perf_counter() - started) * 1000.0
    if proc.returncode != 0:
        detail = (proc.stderr or proc.stdout or "").strip()

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Library source paths are resolved from configuration and iterated with no workspace-boundary enforcement, so the skill can index and read files from arbitrary filesystem locations. In an agent context, that expands the data-access surface beyond what a user may expect from a documentation retrieval skill and can expose sensitive local files if configuration is modified or overly broad.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code makes outbound HTTP embedding requests via a configurable base URL even though the skill is described as local SQLite retrieval. During indexing and vector search, document text and queries are sent off-process and potentially off-host, creating an integrity and confidentiality gap between the documented capability and actual behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The embedding request payload includes raw chunk text and queries, which transmits indexed document content to the configured HTTP endpoint without in-band user disclosure in this file. If the endpoint is remote, compromised, or misconfigured, proprietary or sensitive documentation content may be exfiltrated during indexing and search.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The skill description explains retrieval and indexing behavior but does not clearly warn users that indexing persists external documentation content and metadata into local SQLite databases under the workspace. This is primarily a transparency and privacy issue: users may ingest copyrighted, sensitive, or bulky corpora without realizing they are being stored durably on disk.

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 instead of an exact pinned version, which makes builds non-reproducible and can unexpectedly pull in different releases over time. In a retrieval skill that processes external documentation corpora and SQLite-backed indexes, this increases supply-chain and stability risk because vulnerable or incompatible versions may be installed without review.

Content

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

text
sqlite-vec>=0.1.9

Unverifiable Dependency: sqlite-vec has 2 known advisory(ies) (CVE-2024-46488 (Heap-based Buffer Overflow in sqlite-vec); CVE-2024-46488 (Heap-based Buffer Overflow in sqlite-vec)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The manifest includes sqlite-vec without pinning to a version known to be free of the cited advisory, so deployments may resolve to an affected release. Because this skill performs local retrieval over SQLite knowledge libraries and may ingest attacker-influenced documentation/index content, a memory-safety flaw such as a heap-based buffer overflow in a native extension can become more dangerous than in a purely passive dependency.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This code invokes index_library(...), which likely reads and updates an index or backing store, but the file itself provides no docstring, comment, or user-facing warning about what data will be processed or modified. The surrounding prints only show progress and mode, not a disclosure that indexing may write to storage or transmit data for embeddings depending on configuration.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This file handles sensitive credentials through embedding_api_key and transmits them in the Authorization header for embedding requests. There is no nearby warning, comment, or user-facing output explaining that credentials may be used and sent to an external service.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.