Back to skill

Security audit

Daily Literature Search

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its literature-monitoring purpose, but its installer makes persistent cron changes by default and contains unsafe shell execution patterns users should review before installing.

Review install.sh before running it. Prefer manual execution or dry-run first, add cron only after you explicitly decide you want unattended daily runs, avoid sourcing .env as shell code, store real API/email/webhook secrets carefully, and verify the referenced literature-review skill path is trusted.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (3)

T06 · System Persistence

Error
Location
install.sh:148
Finding
Installer Automatically Establishes User-Level Cron Persistence<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:148-174` **Vulnerability Type**: Automatic scheduled-task persistence **Risk Level**: High ### Complete Vulnerable Code ```bash # Setup cron job setup_cron() { log_info "Setting up cron job..." if ! command -v crontab &> /dev/null; then log_warning "crontab not available. Skipping cron setup." log_info "You can manually add the following line to your crontab:" echo " ${CRON_TIME} * * * python3 ${SCRIPT_DIR}/scripts/daily_literature_search.py >> ${SCRIPT_DIR}/logs/cron.log 2>&1" return fi # Create cron entry CRON_ENTRY="${CRON_TIME} * * * python3 ${SCRIPT_DIR}/scripts/daily_literature_search.py >> ${SCRIPT_DIR}/logs/cron.log 2>&1" if [ "$UNINSTALL" = true ]; then # Remove existing cron entry (crontab -l 2>/dev/null | grep -v "daily_literature_search.py") | crontab - log_success "Cron job removed." else # Add cron entry (avoid duplicates) TEMP_CRON=$(mktemp) crontab -l 2>/dev/null | grep -v "daily_literature_search.py" > "$TEMP_CRON" || true echo "$CRON_ENTRY" >> "$TEMP_CRON" run_or_dry "crontab $TEMP_CRON" rm -f "$TEMP_CRON" log_success "Cron job installed: Daily search at ${CRON_TIME// /:}" fi } ``` The behavior is also disclosed in `README.md:42-49` and `SKILL.md:101-108`. ### Technical Analysis The default installation process modifies the current user's crontab and schedules the project script to execute every day. This behavior persists across terminal sessions, user logins, and individual skill invocations. Daily scheduling is related to the declared literature-monitoring functionality and is documented rather than concealed. Nevertheless, persistent execution is not necessary for installation or manual operation. Installing it automatically, without a dedicated opt-in flag or confirmation prompt, exceeds the minimum privileges ...[truncated 1405 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not install a cron entry during the default installation path. 2. Require an explicit option such as: ```bash ./install.sh --enable-cron ``` 3. Before modifying the crontab, display the exact entry and request affirmative user confirmation. 4. Add a unique marker to the managed entry: ```cron # daily-literature-managed-entry 30 6 * * * /usr/bin/python3 /absolute/path/scripts/daily_literature_search.py ``` 5. During uninstallation, remove only the uniquely marked entry instead of filtering every line containing the script name. 6. Verify that the project directory and executable modules are not writable by untrusted users. 7. Use absolute paths for Python, the configuration file, and log destinations. 8. Document how to inspect, disable, and remove the scheduled task. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
install.sh:62
Finding
Arbitrary Shell Command Execution Through eval and Unvalidated Configuration Paths<![CDATA[ ## Vulnerability Details **File Locations**: `install.sh:62-68`, `install.sh:108-126` **Vulnerability Type**: Shell command injection **Risk Level**: High ### Complete Vulnerable Code The installer evaluates assembled command strings: ```bash run_or_dry() { if [ "$DRY_RUN" = true ]; then echo -e "${YELLOW}[DRY-RUN]${NC} Would execute: $1" else eval "$1" fi } ``` A path is extracted from an existing configuration file as raw text and embedded into those command strings: ```bash # Create directory structure create_directories() { log_info "Creating directory structure..." # Read config or use defaults if [ -f "$CONFIG_FILE" ]; then PAPERS_DIR=$(grep "^papers_dir:" "$CONFIG_FILE" | cut -d':' -f2- | tr -d ' ' | sed 's/\${HOME}/'$HOME'/g') else PAPERS_DIR="${HOME}/.openclaw/workspace/papers" fi # Create category directories for dir in "B-ALL/raw" "MM/raw" "OTHER/raw"; do run_or_dry "mkdir -p ${PAPERS_DIR}/${dir}" done # Create log directory run_or_dry "mkdir -p ${PAPERS_DIR}/daily_search_logs" # Create upload directory run_or_dry "mkdir -p ${PAPERS_DIR}/upload_temp/incoming" log_success "Directory structure created." } ``` ### Technical Analysis `eval` reparses its argument as shell syntax. Consequently, shell metacharacters, command substitutions, redirections, separators, and expansions contained in `PAPERS_DIR` are interpreted as executable shell code rather than as a literal path. The value is obtained using `grep`, `cut`, `tr`, and `sed`, not a YAML parser. It is neither safely quoted nor validated before being interpolated into commands passed to `eval`. A crafted `papers_dir` value can therefore append commands to the intended `mkdir` operation. For example, an existing configuration could contain a value conceptually equivalent to: ```yaml papers_dir: /tmp/papers; attacker_command ``` When the installer evaluat ...[truncated 1386 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `eval` entirely. 2. Implement dry-run handling with argument arrays so commands are never reparsed as shell source. For example: ```bash run_or_dry() { if [ "$DRY_RUN" = true ]; then printf '[DRY-RUN] Would execute:' printf ' %q' "$@" printf '\n' else "$@" fi } run_or_dry mkdir -p -- "$PAPERS_DIR/$dir" ``` 3. Parse `config.yaml` with a YAML parser rather than a `grep | cut | sed` pipeline. 4. Validate that `papers_dir` is a nonempty absolute or explicitly permitted user-relative path. 5. Quote every path expansion and use `--` before path arguments where supported. 6. Reject control characters and unexpected value types. 7. Add tests covering spaces, semicolons, command substitutions, quotes, newlines, and leading hyphens in configured paths. 8. Treat configuration files distributed with or loaded by the installer as untrusted input. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Mutable and Globally Installed Python Dependencies Create Supply-Chain Exposure<![CDATA[ ## Vulnerability Details **File Locations**: `requirements.txt:1-8`, `install.sh:94-102` **Vulnerability Type**: Unpinned third-party dependencies and installation into the active Python environment **Risk Level**: Medium ### Complete Vulnerable Code The dependencies use open-ended minimum-version constraints: ```text # Daily Literature Search Skill - Dependencies # Install: pip install -r requirements.txt # HTTP requests for API calls requests>=2.28.0 # YAML configuration support pyyaml>=6.0 ``` The installer installs these packages through the active `pip3` executable: ```bash # Install Python dependencies install_dependencies() { log_info "Installing Python dependencies..." if [ -f "${SCRIPT_DIR}/requirements.txt" ]; then run_or_dry "pip3 install -r ${SCRIPT_DIR}/requirements.txt" log_success "Dependencies installed." else log_warning "requirements.txt not found. Skipping dependency installation." fi } ``` ### Technical Analysis The `>=` constraints allow any future release satisfying the minimum version. The project therefore does not define a reproducible, reviewed dependency set. It also does not require package hashes or explicitly constrain the package index. The package names `requests` and `pyyaml` are established packages, and the reviewed source contains no evidence that they are intentionally malicious or typographically spoofed. The risk arises from mutable dependency resolution: a compromised future release, compromised configured index, malicious mirror, or altered name-resolution environment could cause the installer to retrieve code that was not included in the audit. Using the active `pip3` without first creating an isolated virtual environment can modify the user's global or otherwise shared Python environment. This may affect unrelated applications and makes it harder to determine which dependency versions are actually used by the scheduled task. ### Attack Path 1. The user ...[truncated 1084 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a project-specific virtual environment and install dependencies only into it: ```bash python3 -m venv "$SCRIPT_DIR/.venv" "$SCRIPT_DIR/.venv/bin/python" -m pip install --require-hashes -r requirements.lock ``` 2. Generate and review a lock file containing exact versions and cryptographic hashes. 3. Use `python3 -m pip` or the virtual environment's interpreter rather than an ambiguous `pip3` executable. 4. Configure and document a trusted package index. 5. Review dependency updates before changing locked versions. 6. Add automated dependency vulnerability and provenance checks. 7. Configure the cron entry to use the exact virtual-environment interpreter so scheduled execution uses the reviewed dependency set. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (38)

Credential Access

High
Category
Privilege Escalation
Content
# Edit config.yaml with your keywords and settings

# Set environment variables
cp .env.example .env
# Edit .env with your email and API keys
source .env
```
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
# Set environment variables
cp .env.example .env
# Edit .env with your email and API keys
source .env
```
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
# Set environment variables
cp .env.example .env
# Edit .env with your email and API keys
source .env
```
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
# Set environment variables
cp .env.example .env
# Edit .env with your email and API keys
source .env
```
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
# Set environment variables
cp .env.example .env
# Edit .env with your email and API keys
source .env
```

### 2. Test Run
Confidence
80% confidence
Finding
The README tells users to 'source .env', which executes the file as shell code rather than merely loading key-value pairs safely. If the .env file is altered maliciously or contains shell metacharacters/commands, sourcing it can execute arbitrary commands in the user's shell session.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
A second independent mismatch finding indicates the skill is represented as a scheduled multi-source literature automation system while the observed behavior is limited and materially different. When a skill's stated purpose diverges from real behavior, it can bypass human review, cause unsafe deployment decisions, and mask collection or file-processing actions that users did not intend to authorize.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
A second independent mismatch finding indicates the skill is represented as a scheduled multi-source literature automation system while the observed behavior is limited and materially different. When a skill's stated purpose diverges from real behavior, it can bypass human review, cause unsafe deployment decisions, and mask collection or file-processing actions that users did not intend to authorize.

Credential Access

High
Category
Privilege Escalation
Content
setup_env() {
    log_info "Setting up environment variables..."
    
    ENV_FILE="${SCRIPT_DIR}/.env"
    
    if [ ! -f "$ENV_FILE" ]; then
        cat > "$ENV_FILE" << EOF
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
setup_env() {
    log_info "Setting up environment variables..."
    
    ENV_FILE="${SCRIPT_DIR}/.env"
    
    if [ ! -f "$ENV_FILE" ]; then
        cat > "$ENV_FILE" << EOF
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# Optionally remove data (commented out for safety)
    # log_warning "Removing data directories..."
    # run_or_dry "rm -rf ${PAPERS_DIR}/daily_search_logs"
    
    log_success "Uninstallation completed."
}
Confidence
95% 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

Medium
Confidence
91% confidence
Finding
The README states that the installer automatically sets up a cron job for daily execution, and the skill also downloads papers and writes logs/files, but it does not prominently warn users about these persistent system changes and local file writes. Hidden persistence and unattended network/file activity increase operational risk, especially for users running install scripts without reviewing them.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# Verify cron job
crontab -l | grep daily_literature

# Or manually add:
# 30 6 * * * python3 /path/to/scripts/daily_literature_search.py
Confidence
85% 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
```bash
# Verify cron job
crontab -l | grep daily_literature

# Or manually add:
# 30 6 * * * python3 /path/to/scripts/daily_literature_search.py
Confidence
85% 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
```bash
# Verify cron job
crontab -l | grep daily_literature

# Or manually add:
# 30 6 * * * python3 /path/to/scripts/daily_literature_search.py
Confidence
85% 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.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The Privacy section says 'All data stored locally' while the same README documents optional external notifications via email/webhooks. This can mislead users into believing no data leaves the host, causing unintentional disclosure of search terms, paper metadata, or report contents to third-party services.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill describes behavior that requires sensitive capabilities including environment-variable access, filesystem reads/writes, network access, and shell execution, but it declares no explicit tool scope or permission boundaries. In agent environments, this can cause the skill to run with broader ambient privileges than users expect, increasing the blast radius if the skill is misused or if its implementation later changes.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The sample daily report is entirely in Chinese, which indicates the skill may generate user-facing output in a fixed language. The file does not state that Chinese output is optional, configurable, or required for a specific regional use case, so this appears to violate the language/locale policy criteria.

Session Persistence

Medium
Category
Rogue Agent
Content
fi
    
    # Check cron
    if ! command -v crontab &> /dev/null; then
        log_warning "crontab not found. Scheduled searches won't work automatically."
    fi
Confidence
85% 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
fi
    
    # Check cron
    if ! command -v crontab &> /dev/null; then
        log_warning "crontab not found. Scheduled searches won't work automatically."
    fi
Confidence
85% 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
91% confidence
Finding
The script creates a plaintext .env file containing placeholders for API keys, webhook URLs, and email credentials, but it does not warn users about local secret storage risks or set restrictive permissions. In an academic automation context, users are likely to populate real credentials, which could then be exposed via weak filesystem permissions, backups, or accidental commits.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest describes a scheduled search pipeline over PubMed, OpenAlex, and Semantic Scholar with deduplication, open-access download, and daily reports. This file instead scans a fixed local upload directory, classifies PDFs by filename heuristics, copies them into topic folders, and writes a local report, which is a materially different workflow than the described search system.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This code file contains natural-language descriptions and user-facing messages exclusively in Chinese, indicating a fixed language/locale experience. The file does not offer any language selection, opt-in, or documented region-specific justification, which matches the language/locale policy violation criteria.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
This skill extends its execution boundary by launching a separate sibling skill from a filesystem path derived from configuration. In a skill ecosystem, that creates a code-execution trust chain: if the sibling skill or its parent directory is tampered with, running this literature search also executes attacker-controlled code.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
Many user-visible strings, including operational logs and generated report content, are hard-coded in Chinese, which forces a specific language experience. The file does not provide a language selection mechanism or explain that the skill is intentionally region- or locale-specific.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
]
    
    try:
        result = subprocess.run(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.