Back to skill

Security audit

kb-framework

Security checks for vulnerabilities and agentic risk

Overview

This knowledge-base skill has useful, coherent features, but it needs Review because installation, updating, LLM processing, and note-writing paths have high-impact access with incomplete scoping and disclosure.

Install only after reviewing the installer and updater behavior. Prefer a virtualenv with locked dependencies, do not use the curl-to-Python bootstrap command, avoid running the OCR sudo installer unless you want host-wide packages installed, keep Ollama bound to localhost unless you intentionally trust the remote endpoint, restrict indexed/source paths to non-sensitive directories, and back up any Obsidian vault before using writer or cleanup commands.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
INSTALL.md:37
Finding
Remote Bootstrap Script Is Downloaded and Executed Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `INSTALL.md:37-39` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: Critical ### Vulnerable Code ```bash python3 -m venv --without-pipe ~/.openclaw/kb/venv ~/.openclaw/kb/venv/bin/python -m ensurepip # or: curl -sS https://bootstrap.pypa.io/get-pip.py | ~/.openclaw/kb/venv/bin/python ``` ### Technical Analysis The installation documentation recommends piping a mutable script retrieved over HTTPS directly into a Python interpreter. No version pin, checksum validation, digital-signature verification, or opportunity for local inspection is provided. HTTPS protects the connection in transit but does not establish that the returned payload is the exact artifact reviewed with this Skill. A compromised distribution server, certificate trust chain, DNS environment, proxy, or upstream publishing process could replace the effective payload after the Skill itself has been audited. Although this command appears in documentation rather than an automatically invoked script, it is presented as an installation procedure and results in direct execution if followed. ### Attack Path 1. A user encounters an environment in which `ensurepip` is unavailable. 2. The user follows the documented alternative command. 3. The command retrieves the current `get-pip.py` response from the external host. 4. The shell streams the response directly into the virtual environment's Python interpreter. 5. Any malicious code in that response executes with the privileges of the user running the installation. ### Impact Assessment Successful exploitation permits arbitrary code execution as the installing user. The payload could read or modify user-accessible files, access environment variables and credentials, install additional packages, alter the OpenClaw workspace, or establish further persistence using the user's existing permissions. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the direct download-to-interpreter pipeline. - Prefer the operating system's reviewed `python3-venv` or `python3-pip` package. - If a bootstrap artifact is unavoidable: 1. Pin it to a specific immutable version. 2. Download it to a local file. 3. Verify a published SHA-256 checksum or trusted digital signature. 4. Inspect the downloaded file before execution. 5. Execute it only inside an isolated virtual environment. - Document the expected artifact hash and the trusted source used to obtain it. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
kb/update.py:128
Finding
Updater Installs Unverified Release Archives and Executes Downloaded Migration Code<![CDATA[ ## Vulnerability Details **File Location**: `kb/update.py:50-72, 128-208, 250-276, 299-304` **Vulnerability Type**: Unverified remote update and code execution **Risk Level**: Critical ### Vulnerable Code The updater obtains mutable release metadata from a user-selectable GitHub repository: ```python def get_latest_release(repo=None): """Fetch latest release info from GitHub API.""" repo = repo or GITHUB_REPO # Validate repo format to prevent injection into URL if not _GITHUB_REPO_PATTERN.match(repo): print(f"❌ Invalid repository format: {repo}. Expected 'owner/repo' with alphanumeric characters.") return None try: url = f"https://api.github.com/repos/{repo}/releases/latest" req = urllib.request.Request(url) req.add_header("Accept", "application/vnd.github.v3+json") req.add_header("User-Agent", "KB-Framework-Updater") with urllib.request.urlopen(req, timeout=10) as response: data = json.loads(response.read().decode()) return { "version": data["tag_name"].lstrip("v"), "url": data["zipball_url"], "published": data["published_at"], "notes": data["body"][:200] + "..." if len(data["body"]) > 200 else data["body"] } except Exception as e: print(f"❌ Error checking latest release: {e}") return None ``` The archive is downloaded and installed without cryptographic artifact verification: ```python def download_and_install(release_info, kb_path, scripts_path): """Download and install latest version.""" import zipfile temp_dir = Path(tempfile.gettempdir()) / "kb_update" temp_dir.mkdir(exist_ok=True) zip_path = temp_dir / "kb_latest.zip" print(f"⬇️ Downloading v{release_info['version']}...") try: urllib.request.urlretrieve(release_info["url"], zip_path) except Exception as e: print(f" ...[truncated 5351 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the production `--repo` option or enforce an exact allowlist containing only the official owner and repository. - Pin updates to immutable commit hashes rather than trusting a mutable “latest” release. - Publish a signed release manifest containing the version, archive digest, expected files, and migration digest. - Verify the archive's SHA-256 hash and publisher signature before extraction or installation. - Reject redirects or download URLs that do not resolve to an explicitly approved host and repository. - Validate every archive member before extraction by resolving its destination and confirming containment inside the extraction directory. - Stage and validate the update before deleting the current installation. - Do not automatically execute migration scripts supplied by an update. Use built-in, versioned migrations already present in reviewed updater code, or require explicit review and confirmation. - Run updates with ordinary user privileges and preserve a transactional rollback path. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
kb/biblio/generator/essence_generator.py:218
Finding
Unrestricted Source Files Can Be Transmitted to an Arbitrary Ollama Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `kb/biblio/config.py:112-113, 202-205`; `kb/biblio/generator/essence_generator.py:218-255, 580-594`; `kb/biblio/engine/ollama_engine.py:130-166, 214-228` **Vulnerability Type**: Arbitrary-file disclosure through unrestricted network configuration **Risk Level**: High ### Vulnerable Code The Ollama endpoint can be supplied through an environment variable, and validation permits any HTTP or HTTPS host: ```python self.ollama_url = self._resolve("KB_LLM_OLLAMA_URL", ollama_url, self.DEFAULT_OLLAMA_URL) ``` ```python def _validate(self) -> None: """Validate LLM configuration.""" if not self.ollama_url.startswith(("http://", "https://")): raise LLMConfigError(f"Invalid Ollama URL: {self.ollama_url}") ``` Source-file paths are not constrained to the configured knowledge-base library: ```python def _read_source_files(self, source_files: List[str]) -> str: """ Read content from source files. Args: source_files: List of file paths to read Returns: Concatenated content from all files """ contents = [] total_bytes = 0 max_total_bytes = 500_000 # ~500KB limit to avoid overwhelming context for file_path_str in source_files: file_path = Path(file_path_str) if not file_path.exists(): logger.warning(f"Source file not found: {file_path}") contents.append(f"[FEHLER: Datei nicht gefunden: {file_path_str}]") continue if not file_path.is_file(): logger.warning(f"Not a file: {file_path}") continue try: content = file_path.read_text(encoding="utf-8", errors="replace") file_size = len(content.encode("utf-8")) if total_bytes + file_size > max_total_bytes: # Truncate to fit remaining = max_total_bytes - total_bytes content = cont ...[truncated 4130 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Resolve every source path and require it to be contained within explicitly configured knowledge-library roots using `Path.resolve()` and `Path.relative_to()`. - Reject symbolic links or resolve them before applying the containment policy. - Deny known sensitive locations and non-document file types. - Default to loopback-only Ollama endpoints such as `127.0.0.1`, `::1`, or a controlled local Unix socket. - Require an explicit security setting and user confirmation before permitting a non-loopback endpoint. - Require HTTPS for all non-loopback endpoints and validate certificates normally. - Maintain an administrator-controlled endpoint allowlist; block link-local, metadata-service, private-network, and redirect destinations unless specifically required. - Display the destination, source filenames, and amount of content that will be transmitted before remote generation. - Apply content minimization or redaction before transmitting documents. - Add tests proving that paths outside approved roots and unapproved remote hosts are rejected. ]]>

T08 · Insecure Dependencies

Warning
Location
install.sh:33
Finding
Dependency Installation Is Not Reproducible or Cryptographically Locked<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:33-40`; `requirements.txt:11-45` **Vulnerability Type**: Unsafe dependency resolution **Risk Level**: Medium ### Vulnerable Code The installation script installs current package-index versions directly: ```bash # 2. Python-Dependencies echo -e "${YELLOW}📦 Installiere Python-Dependencies...${NC}" pip install chromadb --quiet 2>/dev/null || echo -e "${YELLOW}⚠️ chromadb installation failed${NC}" pip install sentence-transformers --quiet 2>/dev/null || echo -e "${YELLOW}⚠️ sentence-transformers failed${NC}" pip install PyMuPDF --quiet 2>/dev/null || echo -e "${YELLOW}⚠️ PyMuPDF failed${NC}" echo -e "${YELLOW}📦 Installiere EasyOCR (optional, für bildbasierte PDFs)...${NC}" pip install easyocr torch --quiet 2>/dev/null || echo -e "${YELLOW}⚠️ EasyOCR/Torch installation failed (optional)${NC}" ``` The core dependency manifest uses broad ranges and no hashes: ```text chromadb>=0.4.0,<2.0.0 sentence-transformers>=2.0.0,<3.0 PyYAML>=6.0 PyMuPDF>=1.23.0 pypdf>=3.0.0 numpy>=1.24.0 requests>=2.28.0 tqdm>=4.65.0 ``` ### Technical Analysis The installer does not use the repository's dependency manifest and instead requests mutable latest versions for several packages. The manifest itself specifies broad lower-bound ranges and does not include artifact hashes. Consequently, two installations performed at different times can resolve to different code, including newly released transitive dependencies that were never reviewed with this Skill. Python packages can execute code during build or installation, making dependency resolution part of the code-execution trust boundary. No evidence of dependency confusion or a known malicious package was found. The issue is the absence of reproducible, integrity-checked dependency controls. ### Attack Path 1. A user runs `install.sh` or installs from `requirements.txt`. 2. `pip` resolves package and transitive dependency versions available at that time. 3. ...[truncated 676 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace direct package-name installations with a reviewed lock file. - Pin every direct and transitive dependency to an exact version. - Generate and enforce SHA-256 hashes with a mechanism such as: ```bash pip install --require-hashes -r requirements.lock ``` - Maintain separate locked files for core, OCR, transformer, and development dependencies. - Install all Python dependencies inside a dedicated virtual environment rather than the ambient interpreter. - Use only approved package indexes and disable unexpected fallback indexes. - Review dependency updates through automated vulnerability scanning and controlled pull requests. - Avoid suppressing installation error output, because doing so conceals integrity, compatibility, and package-source failures. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
install.sh:20
Finding
Default Installer Requests System-Wide Administrative Privileges for Optional OCR Support<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:20-29` **Vulnerability Type**: Excessive installation privileges **Risk Level**: Medium ### Vulnerable Code ```bash # 1. System-Dependencies: Tesseract OCR + Sprachpakete if ! command -v tesseract &> /dev/null; then echo "Installing tesseract-ocr..." sudo apt-get update -qq 2>/dev/null || true sudo apt-get install -y -qq tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng 2>/dev/null || \ apt-get install -y tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng 2>/dev/null || \ echo -e "${YELLOW}⚠️ Tesseract-Installation fehlgeschlagen (keine Root-Rechte?)${NC}" else echo -e "${GREEN}✓${NC} tesseract-ocr bereits installiert" fi ``` ### Technical Analysis The default Skill installer invokes `sudo apt-get` automatically when Tesseract is absent. OCR is an optional extension to the main knowledge indexing and search functions, yet its installation is mixed into the default setup flow. This expands the trust boundary from user-local Python files to system-wide package management. It also causes the installer to request administrative authentication without first separating or clearly confirming the privileged operation. The package names are fixed and no shell injection was identified. The finding concerns violation of least privilege rather than an identified privilege-escalation exploit. ### Attack Path 1. A user runs the general Skill installation script. 2. Tesseract is not already installed. 3. The script automatically invokes `sudo apt-get update` and `sudo apt-get install`. 4. The user authorizes administrative access. 5. System-wide package metadata and packages are modified as part of an otherwise user-local Skill installation. If the installer or its source is compromised before execution, users may be conditioned to approve an administrative prompt, increasing the impact of malicious modifications. ### Impact Assessment The current commands install fixed opera ...[truncated 371 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Keep the default installation entirely unprivileged. - Move OCR system dependencies into a separate, explicitly optional setup document or `--with-ocr` installation mode. - Print the exact administrative commands and require explicit confirmation before invoking them. - Prefer instructing administrators to install system packages separately rather than invoking `sudo` from the Skill installer. - Detect Tesseract and gracefully disable OCR when it is unavailable. - Do not suppress package-manager error output; preserve diagnostics for review. - Clearly document which features require system-wide packages and why those privileges are necessary. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (261)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
# Symlink entfernen und Backup zurückspielen
rm ~/.openclaw/kb
cp -r <backup-pfad> ~/.openclaw/kb
```
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

High
Confidence
97% confidence
Finding
Setting `trust_remote_code=True` allows HuggingFace to import and execute Python code supplied by the remote model repository during model loading. If an attacker controls the repository, compromises it, or convinces a user to load an untrusted model, this becomes arbitrary code execution in the local process, which is especially dangerous because this engine runs models in-process and may have access to filesystem, network, secrets, and GPU resources.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The file is presented and scheduled as an audit/check script, but the appended cleanup routine performs DELETE operations on production tables. That mismatch is dangerous because operators may run or reuse the script expecting read-only integrity checks, while the code contains destructive database logic that can remove records and alter evidence during troubleshooting or maintenance.

Credential Access

High
Category
Privilege Escalation
Content
test_paths = [
        str(Path.home() / "file.txt"),
        "relative/path/file.md",
        "../../../etc/passwd",
        str(Path.home() / "../../../etc/passwd"),
        "file\x00.txt",
    ]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
test_paths = [
        str(Path.home() / "file.txt"),
        "relative/path/file.md",
        "../../../etc/passwd",
        str(Path.home() / "../../../etc/passwd"),
        "file\x00.txt",
    ]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This markdown file documents planned write access to an Obsidian vault, including overwriting, moving, syncing, and deleting notes. Although the operations are described functionally, there is no clear warning to users that these actions can modify or remove existing vault data and should be used carefully.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This markdown file documents `VaultWriter` methods that create, update, move, replace, and delete notes, which directly affect user data. The section presents these operations as examples but does not include any warning about overwriting, moving, or deleting files in the vault.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The `KBUpdate` section states that the updater checks GitHub releases and performs forced or normal updates, which implies outbound network access and software changes. The documentation does not warn users that running update commands may contact external services and modify the local installation.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The `FileWatcher` and `TaskScheduler` sections describe continuous directory monitoring and scheduled LLM jobs, which can process user documents automatically over time. The markdown does not disclose the privacy or data-handling implications of automatic file observation and downstream LLM processing.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documentation instructs users to index, sync, and audit local directories, which implies ingestion of potentially sensitive file contents into SQLite and ChromaDB storage. Because there is no prominent warning about what data is collected, where it is stored, and how long it persists, users may unknowingly expose private documents to local indexing and later downstream processing.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The engine-management section documents use of an external Ollama instance but does not clearly warn that prompts or document-derived content may be transmitted to another local or remote service boundary. In a knowledge-base tool, retrieved or generated content can include sensitive indexed material, so lack of disclosure increases the risk of unintended data exposure.

File System Enumeration

Medium
Category
Data Exfiltration
Content
```bash
# Prüfe ob Verzeichnis existiert
ls -la ~/.openclaw/kb/chroma_db/

# Repair permissions
chmod 755 ~/.openclaw/kb/chroma_db/
Confidence
60% confidence
Finding
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
ls -la ~/.openclaw/kb/chroma_db/

# Repair permissions
chmod 755 ~/.openclaw/kb/chroma_db/

# Full Re-Sync
kb sync --full
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
Falls `ensurepip` nicht verfügbar (Debian/Ubuntu):

```bash
sudo apt install python3.12-venv
# oder:
python3 -m venv --without-pipe ~/.openclaw/kb/venv
~/.openclaw/kb/venv/bin/python -m ensurepip
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The sync command documentation advertises a `--delete-orphans` option but does not prominently warn that it can remove indexed data. Users may run maintenance commands from examples or habit and unintentionally delete records, especially in a system that synchronizes multiple stores (ChromaDB and SQLite).

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README promotes file watching, indexing, syncing, and LLM-based report generation over user documents without clearly warning that these features may continuously read, transform, and persist potentially sensitive content. In a knowledge-base/agent context, users may reasonably enable these capabilities on personal or enterprise document stores, creating privacy and data-handling risks if they do not understand what content is being processed or retained.

Session Persistence

Medium
Category
Rogue Agent
Content
config = LLMConfig.get_instance()
print(f"Model: {config.model}, Source: {config.model_source}")

# Create engine (single-source or auto mode)
engine = create_engine(config)

# Access registry for multi-engine modes
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
# and explains why they are necessary for the framework's functionality.

================================================================================
WRITE OPERATIONS
================================================================================

1. Indexer (kb/commands/index.py)
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill advertises file watching and scheduled jobs that can automatically process user content over time, but it gives no warning that monitoring may be continuous and unattended. This is risky because users may enable background processing without understanding that newly added or changed files could be ingested and sent through LLM-related workflows automatically.

Session Persistence

Medium
Category
Rogue Agent
Content
### 4. Add CLI Alias
```bash
# Add to .bashrc for global access:
alias kb="bash ~/.openclaw/kb/kb.sh"
source ~/.bashrc
```
Confidence
90% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
config = LLMConfig.get_instance()
print(f"Source: {config.model_source}")

# Create engine (auto mode mit HF primary + Ollama fallback)
engine = create_engine(config)

# Registry für Multi-Engine Zugriff
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documentation explicitly describes storing absolute file paths, metadata, and full section content in local databases, but does not warn users that sensitive local content will be persistently collected and indexed. In a knowledge-base skill that processes arbitrary user files, this creates a real privacy and data-exposure risk if users index confidential material or if the database is later accessed by other local processes.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation recommends a deletion-capable orphan cleanup command without any caution about data removal or recovery. Users could run destructive cleanup against misdetected or recently moved content and lose indexed records or associated data unintentionally.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# 1. System-Dependencies: Tesseract OCR + Sprachpakete
if ! command -v tesseract &> /dev/null; then
    echo "Installing tesseract-ocr..."
    sudo apt-get update -qq 2>/dev/null || true
    sudo apt-get install -y -qq tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng 2>/dev/null || \
    apt-get install -y tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng 2>/dev/null || \
    echo -e "${YELLOW}⚠️  Tesseract-Installation fehlgeschlagen (keine Root-Rechte?)${NC}"
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# 1. System-Dependencies: Tesseract OCR + Sprachpakete
if ! command -v tesseract &> /dev/null; then
    echo "Installing tesseract-ocr..."
    sudo apt-get update -qq 2>/dev/null || true
    sudo apt-get install -y -qq tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng 2>/dev/null || \
    apt-get install -y tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng 2>/dev/null || \
    echo -e "${YELLOW}⚠️  Tesseract-Installation fehlgeschlagen (keine Root-Rechte?)${NC}"
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
kb/biblio/engine/transformers_engine.py:396

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test_module_split.py:28