Back to skill

Security audit

Boof

Security checks for vulnerabilities and agentic risk

Overview

This document-processing skill is mostly coherent, but its script can run unintended Python code from crafted file paths and its setup pulls unpinned external dependencies.

Review carefully before installing. Use this only on trusted local paths, avoid files with unusual crafted names, and prefer a patched version that passes paths as Python arguments and pins dependency versions or commits.

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

Error
Location
scripts/boof.sh:121
Finding

Arbitrary Python Code Execution Through Unsafely Interpolated Paths

Content
View full analysis

Vulnerability Details

File Location: scripts/boof.sh, lines 121-127
Vulnerability Type: Python source injection through an unquoted here-document
Risk Level: High

Vulnerable Code

bash
"$ODL_PYTHON" - 2>&1 <<PYEOF | grep -v "^Mar\|^INFO\|^WARNING" | sed 's/^/   /' || true
import opendataloader_pdf
opendataloader_pdf.convert(
    input_path=["$INPUT_FILE"],
    output_dir="$OUTPUT_DIR/",
    format="markdown"
)
PYEOF

Technical Analysis

The here-document delimiter is not quoted, so the shell expands INPUT_FILE and OUTPUT_DIR before sending the generated program to Python. Both variables can contain user-controlled text:

  • INPUT_FILE is populated from a positional command-line argument.
  • OUTPUT_DIR is populated from --output-dir or BOOF_OUTPUT_DIR.

These values are inserted directly between Python quotation marks without Python-string escaping. A value containing quotation marks and Python expressions can terminate the intended string literal and introduce executable Python syntax.

Shell-level quoting around "$INPUT_FILE" elsewhere in the script does not protect this generated Python source. The || true pipeline suffix also suppresses conversion errors, potentially making exploitation attempts less visible.

Attack Path

  1. An attacker creates or supplies a document whose filename contains Python syntax, or persuades the user to invoke the script with a crafted --output-dir.
  2. The user or agent runs boof.sh on that path.
  3. Lines 121-127 interpolate the crafted value into the Python program.
  4. The injected expression is parsed and evaluated by the configured ODL Python interpreter.
  5. The payload can invoke modules such as os or subprocess and execute operating-system commands with the privileges of the user running the Skill.

For example, a filename can be structured so that its injected portion closes the first list element and add ...[truncated 836 chars]

Remediation
View remediation

Remediation Suggestions

Do not construct Python source by interpolating path values. Pass paths as positional arguments and use a quoted here-document:

bash
"$ODL_PYTHON" - "$INPUT_FILE" "$OUTPUT_DIR" <<'PYEOF'
import sys
import opendataloader_pdf

input_file = sys.argv[1]
output_dir = sys.argv[2]

opendataloader_pdf.convert(
    input_path=[input_file],
    output_dir=output_dir,
    format="markdown",
)
PYEOF

In addition:

  1. Remove || true so conversion failures are not silently ignored.
  2. Validate that options requiring values actually have a following argument before reading $2.
  3. Reject embedded NUL or newline characters where appropriate.
  4. Canonicalize paths and apply output-directory restrictions if callers should not be able to write to arbitrary locations.
  5. Add regression tests using filenames containing quotes, backslashes, spaces, Unicode characters, newlines, and Python-like expressions.

T08 · Insecure Dependencies

Warning
Location
references/setup-guide.md:32
Finding

Unpinned Dependencies Allow Unreviewed Supply-Chain Code Changes

Content
View full analysis

Vulnerability Details

File Locations: references/setup-guide.md, lines 32-40 and 49-54; also referenced by scripts/boof.sh, lines 7-10, 84, and 97
Vulnerability Type: Unpinned Python package and mutable Git dependency installation
Risk Level: Medium

Vulnerable Code

Python installation instructions:

bash
# Create isolated Python venv
python3 -m venv ~/.openclaw/tools/odl-env

# Install opendataloader-pdf
~/.openclaw/tools/odl-env/bin/pip install -U opendataloader-pdf

# Verify
~/.openclaw/tools/odl-env/bin/python3 -c "import opendataloader_pdf; print('OK')"

QMD installation instructions:

bash
# Install via bun (NOT npm — the npm package is a placeholder)
bun install -g https://github.com/tobi/qmd

# Verify
~/.bun/bin/qmd status

Technical Analysis

opendataloader-pdf is installed with -U but without an exact version or package hash. Consequently, setup resolves whatever release is current at installation time.

QMD is installed directly from a GitHub repository URL without an immutable commit identifier. A repository’s default branch is mutable, so separate users or installations can receive different code even though they execute the same documented command.

Both dependencies are later imported or executed with the user’s privileges. A compromised maintainer account, malicious release, repository compromise, or unsafe future upstream change could therefore introduce code that was not present during this audit.

No evidence in the audited project establishes that either current upstream dependency is malicious. The issue is the absence of reproducible, integrity-verified dependency resolution.

Attack Path

  1. An attacker compromises an upstream release process, package account, or mutable repository branch.
  2. The attacker publishes modified dependency code.
  3. A user follows the setup guide or performs an upgrade.
  4. pip install -U resolves the c ...[truncated 687 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin opendataloader-pdf to a reviewed exact version:

    bash
    pip install "opendataloader-pdf==REVIEWED_VERSION"
    
  2. Maintain a requirements or lock file containing hashes and install with hash verification:

    bash
    pip install --require-hashes -r requirements.txt
    
  3. Pin QMD to a reviewed immutable commit rather than a mutable default branch.

  4. Record dependency versions and integrity values in the project so installations are reproducible.

  5. Use an automated dependency update process that performs security review and testing before changing pins.

  6. Avoid recommending unconditional upgrades in normal setup instructions.

  7. Verify downloaded artifacts or source revisions before installation and document a controlled procedure for updating them.

Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill description includes very broad triggers such as 'read/analyze/summarize a PDF', 'process a document', and 'extract information', which overlap with many ordinary user requests. This can cause the agent to invoke the skill in situations where a narrower or safer workflow would be more appropriate, increasing the chance of unintended file handling or overbroad document processing.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · references/setup-guide.md (reported line 33)May include surrounding context.

opendataloader-pdf runs fully locally. No API keys, no cloud, no GPU. Processes 100+ pages/sec in fast mode.

bash
# Create isolated Python venv
python3 -m venv ~/.openclaw/tools/odl-env

# Install opendataloader-pdf

Static analysis

No suspicious patterns detected.