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## 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
## 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## 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
## 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)

Lp3

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.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"--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()
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Context-Inappropriate Capability

Medium
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.

Description-Behavior Mismatch

Medium
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.

Missing User Warnings

Medium
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.

Missing User Warnings

Low
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.

Unpinned Dependencies

Low
Category
Supply Chain
Content
sqlite-vec>=0.1.9
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.

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.

Missing User Warnings

Low
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.

Missing User Warnings

Low
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.

Static analysis

No suspicious patterns detected.