Back to skill

Security audit

OpenClaw AntSeed

Security checks for vulnerabilities and agentic risk

Overview

The skill is purpose-aligned but needs Review because its setup path can install persistent system services, route future model traffic through a P2P network, and contains unsafe argument handling that can enable code or service-file injection.

Review before installing. Use a temporary foreground proxy first, avoid the --service option unless you explicitly want a reboot-persistent background process, and do not route secrets or regulated data through the P2P provider network unless you trust the providers. Treat the setup script as unsafe with untrusted arguments, and prefer pinned package versions plus manual review of OpenClaw configuration changes.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T06 · System Persistence

Error
Location
scripts/setup.sh:137
Finding
Reboot-Persistent System Service Installation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:137-157` **Vulnerability Type**: System-wide service persistence **Risk Level**: High ### Vulnerable Code ```bash if [ "$INSTALL_SERVICE" = true ]; then echo "==> Installing systemd service..." ANTSEED_BIN=$(command -v antseed) sudo tee /etc/systemd/system/antseed-buyer.service > /dev/null <<SERVICE [Unit] Description=AntSeed Buyer Proxy After=network-online.target Wants=network-online.target [Service] Type=simple User=$(whoami) ExecStart=${ANTSEED_BIN} connect --router local-proxy --port ${PORT} Restart=on-failure RestartSec=10 StandardOutput=journal StandardError=journal SyslogIdentifier=antseed-buyer [Install] WantedBy=multi-user.target SERVICE sudo systemctl daemon-reload sudo systemctl enable --now antseed-buyer echo " Service installed and started" ``` The same persistence procedure is explicitly documented in `SKILL.md:47-68`. ### Technical Analysis When the `--service` option is supplied, the setup script uses `sudo` to create a system-wide systemd unit under `/etc/systemd/system`. It then enables and immediately starts the service. The service survives the Skill run, user logout, and system reboot. Running the proxy continuously may be convenient, and the behavior is disclosed through the option and documentation. However, system-wide persistence is not necessary for the Skill's minimum declared functionality: the proxy can operate as an ordinary foreground process. A user-level systemd unit would also satisfy most persistence requirements without modifying system-wide startup configuration. The persisted executable comes from a globally installed, unpinned npm package and connects to an external P2P network. The unit has no meaningful systemd sandboxing controls such as `NoNewPrivileges`, `ProtectSystem`, `ProtectHome`, `PrivateTmp`, or restrictive network policies. ### Attack Path 1. A user runs `scripts/setup.sh` with the `--service` option or follows the ...[truncated 1037 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Keep foreground execution as the default and request explicit confirmation before installing any persistent service. 2. Prefer a user-level unit under `~/.config/systemd/user/` and use `systemctl --user`, avoiding sudo and `/etc/systemd/system`. 3. If a system service is genuinely required, apply systemd hardening controls, including: - `NoNewPrivileges=true` - `PrivateTmp=true` - `ProtectSystem=strict` - `ProtectHome=true` or a narrowly scoped alternative - `ProtectKernelTunables=true` - `ProtectControlGroups=true` - `RestrictSUIDSGID=true` - A restrictive `UMask` - Explicitly limited writable paths and network access 4. Pin and verify the executable and plugin versions before registering them for startup. 5. Provide an uninstall operation that stops, disables, and removes the unit, followed by `systemctl daemon-reload`. 6. Clearly disclose that the process connects to a P2P network and remains active after reboot. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup.sh:108
Finding
Python Code Injection Through Unvalidated Setup Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:108-132` **Vulnerability Type**: Code injection through dynamically constructed Python source **Risk Level**: High ### Vulnerable Code ```bash python3 -c " import json, sys cfg = json.load(open('${OPENCLAW_CONFIG}')) # Set up model provider providers = cfg.setdefault('models', {}).setdefault('providers', {}) providers['antseed'] = { 'baseUrl': 'http://127.0.0.1:${PORT}', 'apiKey': 'antseed-p2p', 'api': 'anthropic-messages', 'models': [{ 'id': '${MODEL}', 'name': '${MODEL_NAME}', 'reasoning': False, 'input': ['text'], 'contextWindow': ${CONTEXT_WINDOW}, 'maxTokens': ${MAX_TOKENS} }] } # Set as default model cfg.setdefault('agents', {}).setdefault('defaults', {}).setdefault('model', {})['primary'] = 'antseed/${MODEL}' json.dump(cfg, open('${OPENCLAW_CONFIG}', 'w'), indent=2) print(' Provider configured: antseed/${MODEL}') print(' Default model set: antseed/${MODEL}') " ``` ### Technical Analysis The script constructs Python source code inside a shell string and directly interpolates values controlled by command-line arguments and environment variables. In particular, `CONTEXT_WINDOW` and `MAX_TOKENS` are inserted as unquoted Python expressions without validation. Consequently, these values are not limited to integers. Any syntactically valid Python expression is evaluated by `python3 -c`. For example, a value shaped like the following executes an operating-system command before resolving to an integer: ```text __import__('os').system('ATTACKER_COMMAND') or 8192 ``` `MODEL`, `MODEL_NAME`, `PORT`, and `OPENCLAW_CONFIG_PATH` are also embedded into Python source without safe parameter passing. Quotes, backslashes, or newlines in those values can terminate their intended string literals and inject additional Python statements. ### Attack Path 1. An attacker influences the arguments used to invoke the setup script, su ...[truncated 1142 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never construct Python source by interpolating shell variables. 2. Pass all values as positional arguments or environment variables and parse them as data. For example: ```bash python3 - "$OPENCLAW_CONFIG" "$PORT" "$MODEL" "$MODEL_NAME" \ "$CONTEXT_WINDOW" "$MAX_TOKENS" <<'PY' import json import sys path, port_text, model, model_name, context_text, max_text = sys.argv[1:] port = int(port_text) context_window = int(context_text) max_tokens = int(max_text) # Safely update the JSON object using these data values. PY ``` 3. Validate numeric arguments before Python is invoked: - Port must contain only decimal digits and be between 1 and 65535. - Context-window and max-token values must be positive integers within documented upper bounds. 4. Validate model identifiers and reject control characters where they are not required. 5. Use atomic configuration updates: create a securely permissioned temporary file in the destination directory, validate the resulting JSON, and atomically rename it. 6. Preserve a backup or support rollback before replacing the existing OpenClaw configuration. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/setup.sh:137
Finding
Systemd Unit Injection Through the Unvalidated Port Argument<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:137-157` **Vulnerability Type**: Privileged configuration injection and persistent code execution **Risk Level**: Critical ### Vulnerable Code ```bash if [ "$INSTALL_SERVICE" = true ]; then echo "==> Installing systemd service..." ANTSEED_BIN=$(command -v antseed) sudo tee /etc/systemd/system/antseed-buyer.service > /dev/null <<SERVICE [Unit] Description=AntSeed Buyer Proxy After=network-online.target Wants=network-online.target [Service] Type=simple User=$(whoami) ExecStart=${ANTSEED_BIN} connect --router local-proxy --port ${PORT} Restart=on-failure RestartSec=10 StandardOutput=journal StandardError=journal SyslogIdentifier=antseed-buyer [Install] WantedBy=multi-user.target SERVICE sudo systemctl daemon-reload sudo systemctl enable --now antseed-buyer echo " Service installed and started" ``` ### Technical Analysis The `--port` value is accepted without numeric or control-character validation and interpolated into an unquoted heredoc used to create a privileged systemd unit. Shell variables can contain newline characters. A malicious multiline port value can therefore terminate the intended `ExecStart` line and insert additional systemd directives. Because `sudo tee` writes the resulting content into `/etc/systemd/system`, attacker-controlled directives become trusted system service configuration. The injected content can potentially reset and replace `ExecStart`, modify `User`, or add other service behavior. The subsequent `daemon-reload` and `enable --now` commands cause systemd to parse and start the modified unit immediately and on future boots. This crosses a privilege boundary: data supplied to an unprivileged script argument controls root-managed service configuration. ### Attack Path 1. An attacker convinces a sudo-capable user or automation process to run setup with both `--service` and a malicious multiline `--port` value. 2. The port begins with a plausibl ...[truncated 1242 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate `PORT` before any use: ```bash if [[ ! "$PORT" =~ ^[0-9]+$ ]] || (( PORT < 1 || PORT > 65535 )); then echo "Error: port must be an integer from 1 to 65535" >&2 exit 1 fi ``` 2. Reject carriage returns, newlines, NUL-equivalent data, and all other unexpected control characters in every value written to a service definition. 3. Avoid generating systemd units through an expanding heredoc. Use a fixed template and substitute only prevalidated values. 4. Prefer a user-level service so service creation does not cross into root-owned system configuration. 5. Before enabling the unit, run `systemd-analyze verify` against the generated file and abort on any warning or error. 6. Restrict service identity and execution paths to fixed, administrator-reviewed values. Do not permit command-line input to influence `User`, `ExecStart`, or security directives. 7. Resolve and verify the executable path, ensure it is not user-replaceable when used by a privileged service, and pin the corresponding package version. ]]>

T08 · Insecure Dependencies

Error
Location
scripts/setup.sh:68
Finding
Execution of Unpinned Third-Party npm Packages<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.sh:68-74` **Vulnerability Type**: Unsafe dependency installation and supply-chain exposure **Risk Level**: High ### Vulnerable Code ```bash echo "==> Installing AntSeed CLI..." if ! command -v antseed &>/dev/null; then npm install -g @antseed/cli fi echo " CLI version: $(antseed --version)" echo "==> Installing buyer proxy plugin..." antseed plugin add @antseed/router-local-proxy </dev/null 2>&1 | tail -3 || true ``` The same unpinned installation commands are documented in `SKILL.md:22-29`. ### Technical Analysis The setup installs `@antseed/cli` and `@antseed/router-local-proxy` without explicit versions, integrity values, or a repository lockfile. Each installation therefore resolves mutable package-registry state at execution time rather than a specific reviewed artifact. npm packages can execute lifecycle scripts during installation. The plugin is subsequently used by a network-facing process and may be registered as a reboot-persistent systemd service. A compromised publisher account, malicious release, or dependency-chain compromise can consequently change the code executed by the Skill after the static Skill package itself has been reviewed. The plugin command redirects diagnostic output and ends with `|| true`, suppressing installation failures. This can leave a partially configured or unexpected installation state while setup continues and reports completion. ### Attack Path 1. A malicious or compromised package version is published under one of the referenced package names, or one of its transitive dependencies is compromised. 2. A user invokes the setup script after the compromised version becomes the package registry's selected release. 3. `npm install -g` downloads the mutable package and can execute its lifecycle scripts with the invoking user's privileges. 4. The plugin installer downloads and installs additional unpinned code. 5. The compromised executable or plugi ...[truncated 698 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin reviewed package versions explicitly, for example `@antseed/cli@<reviewed-version>` and `@antseed/router-local-proxy@<reviewed-version>`. 2. Use a project-local installation with a committed lockfile rather than a global mutable installation. 3. Verify package provenance, registry source, signatures where available, and integrity hashes before execution. 4. Review transitive dependencies and use automated vulnerability and provenance scanning. 5. Consider initially installing with lifecycle scripts disabled and only enabling required scripts after review. 6. Remove `|| true`; treat plugin installation failure as a fatal error and preserve actionable diagnostics. 7. Verify the installed CLI and plugin versions before configuration or service registration. 8. Do not register dependency-supplied executables for persistent startup until their versions and integrity have been verified. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (17)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill performs file-modifying actions, including overwriting the user's OpenClaw configuration and creating a systemd unit, but it declares no tool scope or permissions metadata. This increases the chance that an agent or user invokes it without clear disclosure that persistent local changes will occur, weakening least-privilege and informed-consent expectations.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill routes LLM prompts and responses through a peer-to-peer provider network but does not clearly warn that user data may be processed by unknown third-party nodes. In this context, prompts can contain sensitive business, personal, or credential-adjacent data, so omission of a privacy warning materially increases exposure risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill instructs the user to create and enable a root-managed systemd service without an upfront warning that this causes persistent system-level modification. Persistent services broaden the blast radius of mistakes, can survive reboots, and may unintentionally expose network functionality long-term.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
To run the proxy as a background service that survives reboots:

```bash
sudo tee /etc/systemd/system/antseed-buyer.service > /dev/null <<'EOF'
[Unit]
Description=AntSeed Buyer Proxy
After=network-online.target
Confidence
90% confidence
Finding
This command writes a new unit file into /etc/systemd/system using sudo, which is a privileged system modification. While the purpose appears legitimate, using elevated privileges in a skill is dangerous because it can establish persistent execution and modify trusted system startup behavior.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now antseed-buyer
```
Confidence
89% confidence
Finding
Reloading systemd with sudo changes the active service manager state and is part of installing a persistent service. Even when intended for convenience, privileged service-management steps can be abused or executed without sufficient user understanding of system-wide impact.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now antseed-buyer
```

Verify: `sudo systemctl is-active antseed-buyer`
Confidence
91% confidence
Finding
Enabling and starting the service with sudo causes the AntSeed proxy to run immediately and persist across reboots. Because the proxy joins a P2P network and exposes a local HTTP endpoint, persistence increases long-term attack surface and the chance of unnoticed operation.

Session Persistence

Medium
Category
Rogue Agent
Content
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now antseed-buyer
```

Verify: `sudo systemctl is-active antseed-buyer`
Confidence
94% confidence
Finding
The skill explicitly enables the AntSeed proxy as a startup service, creating session persistence. In this context, persistence is more sensitive because the service automatically reconnects to a P2P network and continues handling model traffic after reboot, potentially without ongoing user awareness.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
sudo systemctl enable --now antseed-buyer
```

Verify: `sudo systemctl is-active antseed-buyer`

## Step 3: Configure OpenClaw model provider
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
```bash
# Restart the gateway to pick up the new provider
sudo systemctl restart openclaw  # or kill and restart the gateway process

# Test the connection
curl -s http://127.0.0.1:5005/v1/models
Confidence
86% confidence
Finding
Restarting the OpenClaw service with sudo is a privileged operational change that affects availability and immediately applies the new provider configuration. In this skill's context, that also activates routing through the P2P proxy, so the command has meaningful security and privacy consequences.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script edits ~/.antseed/config.json directly to add bootstrap nodes without any confirmation, backup, or dry-run output. Even though this is part of its stated purpose, silent modification of persistent user configuration can unexpectedly change network trust and routing behavior, especially because the bootstrap node may be user-supplied or operationally sensitive.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script rewrites the OpenClaw configuration file and sets the default model provider to AntSeed without prompting the user or preserving prior defaults. This is risky because it persistently changes how future LLM requests are routed, potentially redirecting sensitive prompts and responses through a peer-to-peer network endpoint.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
if [ "$INSTALL_SERVICE" = true ]; then
  echo "==> Installing systemd service..."
  ANTSEED_BIN=$(command -v antseed)
  sudo tee /etc/systemd/system/antseed-buyer.service > /dev/null <<SERVICE
[Unit]
Description=AntSeed Buyer Proxy
After=network-online.target
Confidence
92% confidence
Finding
The script invokes sudo to write a unit file into /etc/systemd/system, introducing a privileged write path based on runtime-expanded values. While intended for legitimate service installation, any unnecessary privileged operation increases risk and should be tightly scoped and clearly separated from unprivileged setup.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
When --service is used, the script installs and starts a persistent systemd service via sudo, but the user only gets an informational message at execution time rather than a strong upfront warning about privileged, persistent system changes. This can surprise users and leaves a long-running network-connected process enabled at boot.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
[Install]
WantedBy=multi-user.target
SERVICE
  sudo systemctl daemon-reload
  sudo systemctl enable --now antseed-buyer
  echo "  Service installed and started"
else
Confidence
90% confidence
Finding
Running sudo systemctl daemon-reload performs a privileged system-wide service manager action. In context this is expected for service installation, but it still represents elevated execution that can affect system service state and should not happen silently in a general setup script.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
WantedBy=multi-user.target
SERVICE
  sudo systemctl daemon-reload
  sudo systemctl enable --now antseed-buyer
  echo "  Service installed and started"
else
  echo ""
Confidence
95% confidence
Finding
The script enables and starts the antseed-buyer service with sudo, causing privileged execution and persistent autorun at boot. In this skill's context, that makes the behavior more sensitive because it creates a long-lived network proxy that may process future model traffic without further user awareness.

Session Persistence

Medium
Category
Rogue Agent
Content
WantedBy=multi-user.target
SERVICE
  sudo systemctl daemon-reload
  sudo systemctl enable --now antseed-buyer
  echo "  Service installed and started"
else
  echo ""
Confidence
96% confidence
Finding
systemctl enable --now creates persistence by starting the buyer proxy immediately and configuring it to launch on boot. For a component that routes AI traffic through a P2P network, persistence materially increases exposure because the proxy remains active beyond the initial setup session and may continue handling sensitive requests.

Missing User Warnings

Low
Confidence
90% confidence
Finding
The skill rewrites the user's OpenClaw configuration file via a shell pipeline and move operation without recommending a backup or validating the resulting JSON. A malformed edit or unexpected environment state could break the user's configuration or silently replace existing provider settings.

Static analysis

No suspicious patterns detected.