Back to skill

Security audit

claw-negotiate

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its SAFE negotiation purpose, but it under-discloses persistent scheduler installation and has weak token/secret handling in its authorization design.

Review this carefully before installing. It can use Telegram and sshsign as part of the advertised workflow, but it may also create a persistent scheduler job on the host and stores/signs authorization tokens in a way that weakens the promised negotiation bounds. Use only in an isolated demo environment unless those issues are fixed and the scheduler behavior is explicitly controlled.

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 (2)

T06 · System Persistence

Error
Location
negotiate_safe/run_safe.py:1097
Finding
Automatic Installation of a Persistent System or OpenClaw Cron Job<![CDATA[ ## Vulnerability Details **File Location**: `negotiate_safe/run_safe.py:1097-1103`, `negotiate_safe/run_safe.py:2810-2974` **Vulnerability Type**: Persistent scheduled-task registration without explicit operator approval **Risk Level**: Critical ### Vulnerable Code ```python # negotiate_safe/run_safe.py:1097-1103 # Install the global cron scan job (idempotent). Both roles # need cron — investor's resume runs from the same loop as # the founder's, just dispatched on the pointer's `role`. interval = os.environ.get("CLAW_NEGOTIATE_SCAN_INTERVAL", CRON_SCAN_DEFAULT_INTERVAL) ok, err = ensure_cron(interval=interval) if not ok and err: sys.stderr.write(f"ensure_cron: {err}\n") ``` ```python # negotiate_safe/run_safe.py:2810-2860 def ensure_cron( interval: str = "30s", runner: "callable | None" = None, system_runner: "callable | None" = None, ) -> tuple[bool, str | None]: """Install the ``negotiate_safe-scan`` cron job if absent.""" prefer_system_cron = runner is None allow_system_fallback = runner is None or system_runner is not None if runner is None: runner = subprocess.run if system_runner is None: system_runner = runner def _fallback(reason: str) -> tuple[bool, str | None]: if not allow_system_fallback: return False, reason ok, fallback_err = _ensure_system_cron(runner=system_runner) if ok: return True, None return False, f"{reason}; system cron fallback failed: {fallback_err}" if prefer_system_cron: ok, err = _ensure_system_cron(runner=system_runner) if ok: return True, None # Fall through to OpenClaw cron only if the deterministic # code-level heartbeat cannot be installed on this host. ``` ```python # negotiate_safe/run_safe.py:2928-2944 add_argv = [ "openclaw", "cron", "add", "--name", CRON_JOB_NAME, "--every", interval, "--system-event", "negotiate_safe_scan", "- ...[truncated 4632 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic scheduler installation from the negotiation mint path. 2. Require a separate, explicit operator action such as: ```bash python3 negotiate_safe/run_safe.py operator-setup --enable-background-scan ``` 3. Display the exact scheduler command, interval, execution identity, state accessed, and network destinations before requesting consent. 4. Prefer OpenClaw's scoped scheduler over modifying the operating-system crontab. 5. Do not use `--keep-after-run` unless persistence is explicitly enabled. 6. Track whether this Skill created the scheduler entry and remove only that owned entry when no active negotiations remain. 7. Add explicit commands such as `disable-background-scan` and `uninstall`. 8. On cancellation, expiration, and successful completion, check whether any active state remains and remove the scheduler when it is no longer required. 9. Quote all executable and directory paths safely if OS cron remains supported. 10. Store logs in a permission-restricted application state directory rather than a predictable shared `/tmp` path, and implement rotation. 11. Document the behavior prominently in `SKILL.md`, README setup instructions, and the authorization prompt. 12. Operate the scheduler under a dedicated, least-privileged service account with access only to this Skill's state. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
negotiate_safe/minting.py:267
Finding
Symmetric APOA Token Secrets Are Published as Public Keys and Verification Can Fail Open<![CDATA[ ## Vulnerability Details **File Location**: `negotiate_safe/minting.py:267-292`, `negotiate_safe/local_protocol.py:52-87`, `negotiate_safe/session_flow.py:35-74`, `negotiate_safe/session_flow.py:125-205` **Vulnerability Type**: Cryptographic key disclosure and fail-open token verification **Risk Level**: High ### Vulnerable Code ```python # negotiate_safe/minting.py:267-292 founder_secret = secrets.token_urlsafe(32) investor_secret = secrets.token_urlsafe(32) (keys_dir / "founder_private.pem").write_text(founder_secret, encoding="utf-8") (keys_dir / "founder_public.pem").write_text(founder_secret, encoding="utf-8") (keys_dir / "investor_private.pem").write_text(investor_secret, encoding="utf-8") (keys_dir / "investor_public.pem").write_text(investor_secret, encoding="utf-8") principal_id = environ.get("USER_DID") or "did:apoa:default" def _payload(role: str, constraints_payload: dict) -> dict: return { "iss": principal_id, "sub": f"did:apoa:{role}-agent", "aud": service, "role": role, "scope": ["offer:submit", "offer:accept", "document:sign"], "constraints": constraints_payload, "exp": expires_at_epoch, } (tokens_dir / "founder.jwt").write_text( create_local_token(payload=_payload("founder", founder_constraints), secret=founder_secret), encoding="utf-8", ) (tokens_dir / "investor.jwt").write_text( create_local_token(payload=_payload("investor", investor_constraints), secret=investor_secret), encoding="utf-8", ) ``` ```python # negotiate_safe/local_protocol.py:52-87 def create_local_token(*, payload: dict[str, Any], secret: str) -> str: header = {"alg": "HS256", "typ": "JWT"} head = _b64url(json.dumps(header, separators=(",", ":")).encode("utf-8")) body = _b64url(json.dumps(payload, separators=(",", ":")).encode("utf-8")) sig = hmac.new(secret.encode("utf-8"), f"{head}.{body}".encode("ascii"), hashlib.sha256).digest() return f"{head}.{body}.{_b64 ...[truncated 6709 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace HS256 with an asymmetric signature algorithm, preferably Ed25519/EdDSA. 2. Generate distinct private and public key material: - Keep the private key exclusively on the originating host. - Publish only the corresponding public key. - Never upload or exchange a symmetric signing secret. 3. Use a maintained JOSE/JWT implementation that enforces an explicit algorithm allowlist. 4. Make signature verification mandatory. If the verification key is absent, empty, malformed, or unreadable, raise an error and terminate authorization processing. 5. Validate all relevant registered and application claims, including: - `alg` - `iss` - `sub` - `aud` - `role` - `scope` - `exp` - Negotiation or session identifier 6. Bind every token cryptographically to one negotiation and one intended verifier to prevent cross-session reuse. 7. Create sensitive directories with mode `0700`. 8. Create private keys and token files atomically with mode `0600`, independent of the process umask. 9. Use accurate key formats and names. Do not use `.pem` unless the content is actually PEM encoded. 10. Rotate existing negotiation keys and invalidate tokens generated by the affected implementation. 11. Add negative tests proving that: - A public key cannot create a valid token. - Missing or unreadable verification keys fail closed. - Altered claims invalidate the signature. - Tokens from another negotiation or audience are rejected. 12. Treat session services and counterparties as untrusted with respect to private signing material, even if transport is authenticated. ]]>
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (70)

Credential Access

High
Category
Privilege Escalation
Content
Copy the example config:

```bash
cp .env.example .env
```

Edit `.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
Edit `.env`:

```bash
nano .env
```

Use `NEGOTIATE_SAFE_BOT_ROLE=founder` on the founder OpenClaw and `NEGOTIATE_SAFE_BOT_ROLE=investor` on the investor OpenClaw.
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
Edit `.env`:

```bash
nano .env
```

Use `NEGOTIATE_SAFE_BOT_ROLE=founder` on the founder OpenClaw and `NEGOTIATE_SAFE_BOT_ROLE=investor` on the investor OpenClaw.
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
87% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
A skill that mainly performs installation/runtime validation but is described as conducting secure negotiation can mislead users into enabling capabilities they do not need. While not necessarily malicious, this mismatch broadens trust and can expose local environment details through diagnostic commands.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The module advertises itself as local and self-contained, but it performs outbound ssh calls to fetch envelope and signature data. That mismatch is security-relevant because operators may approve or sandbox the skill under the assumption that it has no network dependency, while it actually transmits identifiers to a remote host and trusts remote responses to populate the executed agreement.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
`load_apoa_token` only verifies the HMAC signature if `pubkey_path` is provided and readable; otherwise it sets `secret = ""` and proceeds to parse and trust the token payload anyway. In this skill, the token carries negotiation constraints, so an attacker who can supply or replace the token file can forge arbitrary constraints, remove bounds entirely, or extend expiration, undermining the user-approved safety envelope the skill claims to enforce.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The code generates token-signing secrets and writes them to disk as both 'private' and 'public' PEM files, even though the manifest describes human-approved sshsign signing. Persisting credential material locally increases the chance of theft, reuse, or misuse, and the identical public/private contents suggest a nonstandard trust model that could mislead downstream consumers.

Missing User Warnings

High
Confidence
96% confidence
Finding
Sensitive credential material is written to disk without user-facing warning and apparently without explicit permission hardening. Any local compromise, backup system, shared workspace, or later process reading those files could obtain the secrets and mint or use negotiation tokens improperly.

Static analysis

No suspicious patterns detected.