Back to skill

Security audit

EvoMap Auto Maintainer

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says at a high level, but it installs an indefinite cron job that repeatedly contacts EvoMap without confirmation, removal controls, or reliable duplicate handling.

Install only if you intentionally want a user-level cron job that runs every 15 minutes and sends authenticated EvoMap heartbeat data to evomap.ai. Before using setup, inspect your crontab, understand how to remove the entry manually, and avoid placing EVOMAP_SECRET where it may be logged, committed, or exposed in shell history.

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

T06 · System Persistence

Error
Location
maintainer.sh:70
Finding
Persistent Cron Job Installed Without Lifecycle Controls<![CDATA[ ## Vulnerability Details **File Location**: `maintainer.sh:70-88` **Vulnerability Type**: Persistent scheduled-task registration **Risk Level**: High ### Vulnerable Code ```bash setup_auto() { log "设置自动维护..." local script_path script_path="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" # 检查是否已有 cron 任务 if crontab -l 2>/dev/null | grep -q "evomap-maintainer"; then log "⚠️ 自动任务已存在" else # 添加 cron 任务 (crontab -l 2>/dev/null; echo "*/15 * * * * $script_path heartbeat >> /tmp/evomap-cron.log 2>&1") | crontab - log "✅ 已设置每15分钟自动心跳" fi log "" log "配置完成!当前设置:" log " 节点ID: $NODE_ID" log " 日志文件: $LOG_FILE" log " 查看日志: tail -f $LOG_FILE" } ``` ### Technical Analysis The `setup` operation modifies the invoking user's crontab and registers the script to execute every 15 minutes. The task survives the current Skill execution, terminal session, and system restart where cron is enabled. Scheduled execution is related to the advertised automatic-heartbeat function and is explicitly documented. However, the implementation does not provide an expiration period, interactive confirmation, disable operation, uninstall operation, or reliable ownership marker. It therefore creates indefinite persistence with no corresponding lifecycle management. The cron job repeatedly invokes a script from its current installation path. If that file or an ancestor directory is subsequently writable by another account or process, modification of the script would convert the existing cron entry into a recurring code-execution mechanism under the crontab owner's privileges. ### Attack Path 1. The user invokes `bash maintainer.sh setup`. 2. The script resolves its absolute path. 3. It appends a cron entry to the user's existing crontab. 4. Cron invokes that path every 15 minutes across future sessions. 5. The task continues generating network requests and logs until the user manually i ...[truncated 733 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require explicit confirmation immediately before modifying the crontab. - Add documented `disable` and `uninstall` commands that remove only entries owned by this Skill. - Add a stable, unique marker such as `# evomap-maintainer` to every managed entry. - Remove stale or duplicate managed entries before installing a new one. - Validate that the script and its parent directories are not writable by untrusted users. - Prefer a user-scoped service or timer with explicit enable, disable, status, and uninstall lifecycle operations. - Clearly disclose the task's persistence, schedule, network destination, log location, and removal procedure. - Consider an expiration period or periodic installation-integrity check rather than indefinite execution. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
maintainer.sh:75
Finding
Incorrect Cron Duplicate Detection Allows Scheduled-Task Accumulation<![CDATA[ ## Vulnerability Details **File Location**: `maintainer.sh:75-81` **Vulnerability Type**: Non-idempotent scheduled-task configuration **Risk Level**: Medium ### Vulnerable Code ```bash # 检查是否已有 cron 任务 if crontab -l 2>/dev/null | grep -q "evomap-maintainer"; then log "⚠️ 自动任务已存在" else # 添加 cron 任务 (crontab -l 2>/dev/null; echo "*/15 * * * * $script_path heartbeat >> /tmp/evomap-cron.log 2>&1") | crontab - log "✅ 已设置每15分钟自动心跳" fi ``` ### Technical Analysis The duplicate check searches the existing crontab for the literal text `evomap-maintainer`, but the generated cron line does not add that identifier. It contains only the resolved script path, the `heartbeat` argument, and the log redirection. In the audited project path, the searched marker is not present. Consequently, invoking `setup` repeatedly can append identical jobs. The operation is not idempotent and does not normalize, update, or remove existing entries before installation. The implementation also rewrites the complete output of `crontab -l` together with the new entry. Although it normally preserves existing jobs, concurrent crontab changes could be lost because there is no locking or atomic ownership-aware update mechanism. ### Attack Path 1. A user invokes `maintainer.sh setup`. 2. The script installs one heartbeat cron entry. 3. The user invokes `setup` again, or automation repeats the setup operation. 4. The marker search does not match the previously generated entry. 5. Another equivalent entry is appended. 6. Every accumulated entry launches a heartbeat process at the same 15-minute interval. ### Impact Assessment Duplicate entries can cause concurrent authenticated requests to `evomap.ai`, unnecessary CPU and network use, remote rate-limit violations, and repeated writes to the shared cron log. The resulting activity runs with the privileges of the affected user. This flaw does not independently grant elevated privileges, but it amplifies the persistenc ...[truncated 69 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Add a unique marker to the installed entry, for example: ```bash */15 * * * * /validated/path/maintainer.sh heartbeat >> /tmp/evomap-cron.log 2>&1 # evomap-maintainer ``` - Match the exact managed marker rather than relying on a possible directory or file name. - Remove all existing entries carrying that marker before adding the canonical entry. - Validate and safely quote the resolved script path. - Implement separate `enable`, `disable`, and `status` operations. - Use locking or a scheduler management mechanism that avoids racing with concurrent crontab updates. - Test repeated setup calls and ensure they leave exactly one managed task. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
maintainer.sh:80
Finding
Scheduled Heartbeat Does Not Reliably Receive Required Credentials<![CDATA[ ## Vulnerability Details **File Location**: `maintainer.sh:8-9, 47-49, 80` **Vulnerability Type**: Unsafe persistent-task configuration and credential provisioning **Risk Level**: Medium ### Vulnerable Code ```bash NODE_ID="${EVOMAP_NODE_ID:-}" NODE_SECRET="${EVOMAP_SECRET:-}" ``` ```bash if [ -z "$NODE_ID" ] || [ -z "$NODE_SECRET" ]; then log "❌ 缺少 NODE_ID 或 NODE_SECRET" return 1 fi ``` ```bash (crontab -l 2>/dev/null; echo "*/15 * * * * $script_path heartbeat >> /tmp/evomap-cron.log 2>&1") | crontab - ``` ### Technical Analysis The heartbeat requires `EVOMAP_NODE_ID` and `EVOMAP_SECRET`, but the installed cron entry does not define those values or load them from a protected configuration source. The documentation instructs the user to export environment variables in an interactive shell. A cron process ordinarily starts with a restricted environment and does not inherit temporary exports from the shell that ran `setup`. As a result, setup can report success even though the installed job lacks the credentials necessary to perform its only operation. Every scheduled invocation then reaches the empty-value check, writes a failure message, and exits. Placing credentials directly in the crontab would create a separate plaintext-secret exposure issue and is not an appropriate fix. Credential material should instead be retrieved from a permission-restricted configuration or operating-system credential facility. ### Attack Path 1. The user exports `EVOMAP_NODE_ID` and `EVOMAP_SECRET` in an interactive shell. 2. The user runs `maintainer.sh setup`, and the script reports successful cron installation. 3. The temporary interactive environment is not retained by cron. 4. Cron invokes `maintainer.sh heartbeat` without the required variables. 5. The heartbeat fails every 15 minutes while the persistent task remains installed. 6. Failure output continues to be appended to `/tmp/evomap-cron.log`. ### Impact Assessment The primary impact is loss ...[truncated 462 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Validate scheduled-mode credential availability before installing the task. - Store configuration in a dedicated file readable only by the user, with permissions such as `0600`, or use an operating-system credential store. - Have the script load the protected configuration explicitly during scheduled execution. - Do not embed bearer tokens directly in command-line arguments or plaintext crontab entries. - Abort setup and avoid modifying the crontab if configuration validation fails. - Add a post-installation test that executes the heartbeat under an environment equivalent to cron. - Apply log rotation or bounded logging to prevent indefinite growth of failure logs. - Ensure failure messages never include the bearer token or complete sensitive server responses. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (11)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises and instructs shell-based operations but does not declare any tool scope such as permissions or allowed-tools. This creates a transparency and least-privilege problem: users and hosting platforms cannot easily evaluate that the skill will invoke shell commands and set up persistence, increasing the chance of unintended command execution in a privileged environment.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill asks the user to export EVOMAP_SECRET but provides no warning about secret sensitivity, storage risks, shell history exposure, or how the secret will be used. Requesting credentials without handling guidance increases the risk of accidental disclosure through terminal history, process environments, logs, screenshots, or inherited subprocess environments.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The setup instructions say the action will be 'permanent' and add cron jobs, but they do not clearly warn the user that this modifies crontab for persistent background execution. Persistence mechanisms are security-sensitive because they survive the current session, may run unattended, and can be abused to keep unwanted automation active or conceal future behavior changes.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
User-facing comments, logs, and help text are written entirely in Chinese, and the skill does not offer any language selection or note that it is intentionally Chinese-only. This can violate language/locale policy when a skill imposes a specific language without user opt-in.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script reads a secret from the environment and uses it as a bearer token in an outbound request, but does not clearly warn the user that a sensitive credential will be consumed for remote authentication. This is risky because users may not realize the skill is transmitting an authentication secret to an external service and may run it in shared or poorly audited environments.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script sends the node identifier and heartbeat metadata to a remote service automatically when the heartbeat command is run, but it does not present a prominent warning or consent prompt at execution time. In a skill marketplace context, silent network transmission can surprise users and may disclose operational metadata to a third party without clear acknowledgement.

External Transmission

Medium
Category
Data Exfiltration
Content
payload="{\"protocol\":\"gep-a2a\",\"protocol_version\":\"1.0.0\",\"message_type\":\"heartbeat\",\"message_id\":\"msg_$(date +%s)_$$\",\"sender_id\":\"$NODE_ID\",\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"payload\":{\"status\":\"alive\",\"credit_balance\":0,\"active_sessions\":1}}"
    
    local response
    response=$(curl -s -X POST "${HUB_URL}/a2a/heartbeat" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $NODE_SECRET" \
        -d "$payload" 2>/dev/null || echo '{"status":"error"}')
Confidence
98% confidence
Finding
This POST request transmits heartbeat data and an Authorization bearer token to an external domain. In context, external transmission is the core purpose of the skill, but it still carries security and privacy risk because it sends authenticated data off-host and could be abused if the endpoint, token handling, or user expectations are not trustworthy.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The setup command persists execution by modifying the user's crontab every 15 minutes, but it does not provide a strong warning about the lasting system change before making it. Persistent scheduled execution increases risk because users may not understand that the script will continue making outbound authenticated requests long after the initial invocation.

Session Persistence

Medium
Category
Rogue Agent
Content
script_path="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")"
    
    # 检查是否已有 cron 任务
    if crontab -l 2>/dev/null | grep -q "evomap-maintainer"; then
        log "⚠️  自动任务已存在"
    else
        # 添加 cron 任务
Confidence
95% confidence
Finding
The code inspects crontab as part of setting up persistence, which is not inherently malicious, but in this context it is directly tied to installing a recurring scheduled task. Persistence mechanisms are sensitive because they cause continued execution and continued authenticated network activity without ongoing user interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
log "⚠️  自动任务已存在"
    else
        # 添加 cron 任务
        (crontab -l 2>/dev/null; echo "*/15 * * * * $script_path heartbeat >> /tmp/evomap-cron.log 2>&1") | crontab -
        log "✅ 已设置每15分钟自动心跳"
    fi
Confidence
99% confidence
Finding
This line installs a cron entry that runs the script every 15 minutes and redirects output to /tmp, creating persistent behavior. In a marketplace skill, silent persistence is dangerous because it can continuously send authenticated heartbeats and remain active after the user forgets it was installed.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
All user-facing descriptive content and examples are presented only in Chinese, and there is no indication that language can be selected or that the skill is region-specific. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Static analysis

No suspicious patterns detected.