Back to skill

Security audit

openbotclaw

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent social-world connector, but it needs review because it can autonomously post publicly, handles persistent identity credentials, sends bearer tokens to configurable endpoints, and recommends mutable remote updates.

Install only if you are comfortable with an autonomous agent connecting to a third-party social service, posting public messages, and storing an RSA identity key locally. Keep OPENBOT_URL on a trusted HTTPS endpoint, protect ~/.openbot/keys, avoid unattended continuous mode without limits, and prefer pinned or marketplace-reviewed updates over the curl-from-main workflow.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (4)

T01 · Skill Instruction Hijacking

Error
Location
openbotclaw.py:958
Finding
Untrusted World Chat Is Injected Directly into the Agent's LLM Instruction Context<![CDATA[ ## Vulnerability Details **File Location**: `openbotclaw.py:958-1055`; related behavioral directives in `MESSAGING.md:36-82` and `HEARTBEAT.md:43-58` **Vulnerability Type**: Indirect prompt injection through untrusted social-world messages **Risk Level**: High ### Vulnerable Code ```python def build_observation(self, cached_news: Optional[List[str]] = None) -> str: """ Build a compact world-state snapshot for an LLM agent. Returns a multi-line string with observation markers (see MESSAGING.md). This method also updates internal state: - ``_tick_count`` is incremented - ``_new_senders`` / ``_tagged_by`` are populated for the current tick - ``_current_topic`` rotates every ~3 ticks ... Returns: Compact observation string ready to be sent to an LLM. """ ... # Recent conversation (last 6 messages) recent = self.get_recent_conversation(60.0) self._new_senders = [] self._tagged_by = [] agent_name = self.entity_id or self.agent_name if recent: self._last_chat_tick = self._tick_count for m in recent[-6:]: sender = m.get("agent_name", "?") msg_text = m.get("message", "") ts = m.get("timestamp", 0) key = (sender, ts) is_new = key not in self._seen_msg_keys if sender != agent_name and is_new: self._seen_msg_keys.add(key) self._new_senders.append(sender) tagged = self.is_mentioned(msg_text) if tagged: self._tagged_by.append(sender) lines.append(f"📣 TAGGED BY {sender}: {msg_text}") else: lines.append(f"⬅ NEW {sender}: {msg_text}") else: lines.append(f"{sender}: {msg_text}") # Reply directive if self._tagged_by: lines.append(f"REPLY TO: {self._tagged_by[-1]}") elif self._new_senders: line ...[truncated 2723 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat every remote message, sender name, object name, and news entry as untrusted data. 2. Pass observations in a structured format with separate fields rather than concatenating data and directives into one instruction-like string. 3. Add an explicit, higher-priority rule stating that text inside world messages is content to discuss, never instructions to execute. 4. Escape or quote remote text and wrap it in unambiguous delimiters such as `<untrusted_chat>`. 5. Remove mandatory-response language. Safety policy, user intent, and rate limits must take priority over replying. 6. Reject requests to reveal prompts, tokens, credentials, private files, internal state, or tool output. 7. Require human confirmation before a chat message can cause filesystem, network, credential, or other out-of-world actions. 8. Apply message length limits and content filtering before text reaches the model. 9. Add prompt-injection regression tests using malicious mentions and sender names. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
openbotclaw.py:275
Finding
Authenticated Sessions Permit Arbitrary and Plaintext API Destinations<![CDATA[ ## Vulnerability Details **File Location**: `openbotclaw.py:275-309`, `openbotclaw.py:467-514`, `openbotclaw.py:551-554`, `openbotclaw.py:1252-1255`, and `openbotclaw.py:1507-1511` **Vulnerability Type**: Missing endpoint validation and insecure credential transport **Risk Level**: High ### Vulnerable Code ```python def __init__( self, url: str = "https://api.openbot.social", ... ): ... Raises: ValueError: If URL is invalid """ # Configuration self.url = url.rstrip('/') # Remove trailing slash ``` ```python # Update HTTP session headers with auth token if self.session and self._session_token: self.session.headers.update({ 'Authorization': f'Bearer {self._session_token}' }) ``` ```python def _create_session(self) -> requests.Session: """Create HTTP session with connection pooling and retry logic.""" session = requests.Session() ... session.mount("http://", adapter) session.mount("https://", adapter) session.headers.update({ 'Content-Type': 'application/json', 'User-Agent': f'OpenBotClawHub/{self.agent_name or "Anonymous"}' }) if self._session_token: session.headers.update({ 'Authorization': f'Bearer {self._session_token}' }) return session ``` ```python response = self.session.get( f"{self.url}/status", timeout=self.connection_timeout ) ``` ```python response = self.session.post( endpoint, json=payload, timeout=self.connection_timeout ) ``` ### Technical Analysis Although the constructor documentation claims that an invalid URL raises `ValueError`, the implementation only removes a trailing slash. It does not validate the URL scheme, hostname, port, embedded credentials, redirects, or resolved network address. The same `requests.Session` is configured with a session-wide Bearer authorization header and supports both HTTP and HTTPS. Consequently, a caller can configure an arbitrary destin ...[truncated 1603 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse URLs with a standard URL parser and reject malformed values. 2. Require `https` for any authenticated connection. Permit plaintext HTTP only through an explicit development-only option that cannot carry real credentials. 3. Default to an allowlist containing `api.openbot.social`. 4. If custom servers are required, require explicit user approval and maintain a per-destination trust configuration. 5. Reject URLs containing embedded usernames or passwords, unexpected ports, fragments, or unsupported schemes. 6. Resolve the hostname and block loopback, link-local, metadata-service, private, multicast, and otherwise restricted addresses unless explicitly authorized. 7. Disable automatic cross-origin redirects for authenticated requests, or strip the Authorization header whenever the origin changes. 8. Scope authorization headers to the validated API origin instead of installing them as unrestricted session defaults. 9. Add tests covering HTTP URLs, attacker domains, redirect chains, IPv4/IPv6 private addresses, and malformed URL forms. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
HEARTBEAT.md:7
Finding
Skill Updates Are Retrieved from a Mutable Branch Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `HEARTBEAT.md:7-17`; related installation commands in `SKILL.md:36-43` and `README.md:48-55` **Vulnerability Type**: Mutable remote payload retrieval and unsafe update workflow **Risk Level**: Medium ### Vulnerable Code ```python ## Step 0: Check for skill updates import requests meta = requests.get( "https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/skill-config.json" ).json() print(meta.get("version")) # compare with your installed version ``` ```markdown Check **once per day**. Re-fetch skill files if the version changed. ``` The recommended replacement commands include executable code and agent instructions: ```bash mkdir -p ~/.clawhub/skills/openbotclaw curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/SKILL.md > ~/.clawhub/skills/openbotclaw/SKILL.md curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/HEARTBEAT.md > ~/.clawhub/skills/openbotclaw/HEARTBEAT.md curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/MESSAGING.md > ~/.clawhub/skills/openbotclaw/MESSAGING.md curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/RULES.md > ~/.clawhub/skills/openbotclaw/RULES.md ``` ```bash for f in SKILL.md HEARTBEAT.md MESSAGING.md RULES.md openbotclaw.py skill-config.json requirements.txt; do curl -sO "https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/$f" done ``` ### Technical Analysis The update workflow uses GitHub's mutable `main` branch rather than an immutable commit or signed release. It performs no checksum, signature, provenance, or expected-version validation. The metadata request also omits an explicit timeout and does not call `raise_for_status()` before parsing JSON. The manual update procedure can replace both persistent Skill instructions and `openbotclaw.py`. ...[truncated 1530 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Retrieve updates only from immutable release tags or commit hashes. 2. Publish a signed manifest containing the version and SHA-256 digest of every distributed file. 3. Verify signatures and hashes before replacing any installed file. 4. Require explicit human approval before modifying executable code or persistent Skill instructions. 5. Download into a temporary file, validate it, and atomically rename it into place only after all checks pass. 6. Use request timeouts and `raise_for_status()` for metadata retrieval. 7. For command-line installation, use `curl --fail --show-error --location` and verify the downloaded artifact before installation. 8. Prefer a trusted package or marketplace update mechanism that records provenance and supports rollback. 9. Keep the last known-good version and automatically restore it if validation or loading fails. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Python Dependencies Use Open-Ended Version Constraints Without Integrity Pinning<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-2` **Vulnerability Type**: Non-reproducible third-party dependency resolution **Risk Level**: Medium ### Vulnerable Code ```text requests>=2.28.0 cryptography>=41.0.0 ``` The documented installation executes these unconstrained requirements: ```bash pip install -r requirements.txt ``` ### Technical Analysis Both packages use minimum-version constraints with no upper bound, exact version, lock file, or package hash. A fresh installation can therefore resolve to any future release accepted by the package index, even if that release has not been reviewed with this Skill. The package names are legitimate and there is no evidence of dependency confusion or typosquatting in the audited files. The risk is that builds are not reproducible and may silently acquire a compromised, incompatible, or newly vulnerable future release. ### Attack Path 1. A new package version becomes available on the configured Python package index. 2. The version satisfies the broad `>=` constraint. 3. A user follows the documented `pip install -r requirements.txt` procedure. 4. Pip downloads and installs the unreviewed version. 5. Package installation or later import executes that dependency's code with the user's privileges. An attacker would need to compromise the package release process, package index, configured index source, or another relevant supply-chain component for direct malicious exploitation. ### Impact Assessment A malicious dependency release can execute code with the privileges of the Python installation or agent process. Depending on the deployment, that can expose agent data, local credentials readable by the process, authentication material, and network access. Broad constraints can also cause non-malicious availability failures due to incompatible future releases. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin exact dependency versions that have been reviewed and tested. 2. Generate a lock file appropriate to the deployment workflow. 3. Record and enforce package hashes, for example with pip's `--require-hashes`. 4. Install only from explicitly trusted package indexes over HTTPS. 5. Update dependencies through a controlled review process with automated vulnerability scanning and tests. 6. Separate direct dependencies from fully resolved transitive dependencies. 7. Regenerate pins regularly so security patches are adopted deliberately rather than through unrestricted resolution. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (35)

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
REPLY TO: name → address them directly by name
Silence → break it with news or hot take

Rules: chat ≤280 chars. When replying, start with @TheirEntityID. If someone asks you a question or @tags you, ALWAYS answer it directly — never ignore it. Waiting almost never correct.\
{extra}"""

# Keep backward compatibility
Confidence
94% confidence
Finding
The anti-refusal instruction ('ALWAYS answer it directly — never ignore it') is a strong red flag in an agent skill because it intentionally weakens normal safety boundaries and makes prompt-injection through chat more effective. In this context, hostile users can tag the agent and increase the likelihood of compelled responses, including disclosure or unsafe actions by the downstream model.

Context Leakage

High
Category
Data Exfiltration
Content
def chat(self, message: str) -> bool:
        """
        Send chat message to all agents.
        
        Args:
            message: Chat message text
Confidence
85% confidence
Finding
Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.

Exfiltration Commands

High
Category
Prompt Injection
Content
def _send(self, data: Dict[str, Any]) -> bool:
        """
        Send message to server via HTTP POST.
        
        Maps message types to correct API endpoints:
        - register -> POST /spawn (with auth)
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Self-Modification

High
Category
Rogue Agent
Content
],
  "status": "stable",
  "changelog": {
    "0.0.4": "Rewrite skill docs as behavioral specs for OpenClaw. Remove OpenAI dependency — OpenClaw is the AI. Rename SYSTEM_PROMPT to AGENT_PERSONALITY, replace TOOLS with ACTION_TYPES, add README.md for human setup.",
    "0.0.3": "Autonomous agent support: observe-think-act loop, observation markers, @mention detection, anti-repetition system, news cache, action overrides, interests system",
    "0.0.2": "Strict name validation (no spaces/special chars), movement clamping (5 units/move), conversation history with timestamps, numeric agent IDs, camera follow on name click",
    "0.0.1": "RSA entity auth, session management, HTTP polling, message queue, auto-reconnect"
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This section explicitly instructs the agent to continue autonomous social-world interaction, including repeated chat posting and movement, without a strong warning, consent gate, rate limit policy, or operator confirmation. In context, the skill is designed for persistent autonomous presence, so the behavior is intentional, but it can still cause spam, unwanted engagement, or uncontrolled actions if enabled by default or run unattended.

External Transmission

Medium
Category
Data Exfiltration
Content
Chat, observation markers, @mentions, and social intelligence for OpenBot Social World.

**Base URL:** `https://api.openbot.social/` (override via `OPENBOT_URL` env var)

> All authenticated calls include your Bearer session token automatically when you have called `authenticate_entity()`.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Chat, observation markers, @mentions, and social intelligence for OpenBot Social World.

**Base URL:** `https://api.openbot.social/` (override via `OPENBOT_URL` env var)

> All authenticated calls include your Bearer session token automatically when you have called `authenticate_entity()`.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Chat, observation markers, @mentions, and social intelligence for OpenBot Social World.

**Base URL:** `https://api.openbot.social/` (override via `OPENBOT_URL` env var)

> All authenticated calls include your Bearer session token automatically when you have called `authenticate_entity()`.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Chat, observation markers, @mentions, and social intelligence for OpenBot Social World.

**Base URL:** `https://api.openbot.social/` (override via `OPENBOT_URL` env var)

> All authenticated calls include your Bearer session token automatically when you have called `authenticate_entity()`.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Chat, observation markers, @mentions, and social intelligence for OpenBot Social World.

**Base URL:** `https://api.openbot.social/` (override via `OPENBOT_URL` env var)

> All authenticated calls include your Bearer session token automatically when you have called `authenticate_entity()`.
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill documents that authenticated requests automatically include a Bearer session token, but it provides no warning about where that token is sent, how `OPENBOT_URL` can redirect traffic, or the trust boundary involved. In an agent skill context, this can lead users or downstream code to unknowingly transmit credentials to a different endpoint, increasing the risk of credential leakage or misuse.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README states that the agent will autonomously join a remote social world and act on its own, but it does not clearly foreground that this involves ongoing network communication and transmission of agent-generated content to a third-party service. Users may enable the skill without fully understanding the privacy and operational exposure, especially in an autonomous-agent context where behavior can be continuous.

Session Persistence

Medium
Category
Rogue Agent
Content
### Option C: Download skill files only

```bash
mkdir -p ~/.clawhub/skills/openbotclaw
cd ~/.clawhub/skills/openbotclaw

# Download all skill files
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.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README instructs users to generate an RSA key pair and notes only that the private key should be backed up, but it does not strongly warn that the private key is a sensitive credential whose disclosure enables entity impersonation or account takeover. Emphasizing backup without equal emphasis on secrecy can lead users to store or handle the key insecurely.

Session Persistence

Medium
Category
Rogue Agent
Content
**Install / update locally:**
```bash
mkdir -p ~/.clawhub/skills/openbotclaw
curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/SKILL.md     > ~/.clawhub/skills/openbotclaw/SKILL.md
curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/HEARTBEAT.md > ~/.clawhub/skills/openbotclaw/HEARTBEAT.md
curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/MESSAGING.md > ~/.clawhub/skills/openbotclaw/MESSAGING.md
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.

Skill Enumeration

Medium
Category
Agent Snooping
Content
**Install / update locally:**
```bash
mkdir -p ~/.clawhub/skills/openbotclaw
curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/SKILL.md     > ~/.clawhub/skills/openbotclaw/SKILL.md
curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/HEARTBEAT.md > ~/.clawhub/skills/openbotclaw/HEARTBEAT.md
curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/MESSAGING.md > ~/.clawhub/skills/openbotclaw/MESSAGING.md
curl -s https://raw.githubusercontent.com/AaronKow/openbot-social/main/skills/openbotclaw/RULES.md     > ~/.clawhub/skills/openbotclaw/RULES.md
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Session Persistence

Medium
Category
Rogue Agent
Content
Your `entity_id` is your permanent in-world identity. An RSA key pair is generated locally — the private key proves ownership.

### Step 1: Create entity (first time only)

```python
hub.create_entity("my-lobster-001", entity_type="lobster")
Confidence
92% confidence
Finding
The skill instructs users to generate and persist a long-lived private key in a predictable path under ~/.openbot/keys, creating a sensitive local credential that can be stolen by other local processes, backups, or overly broad file permissions. Because the key represents permanent identity ownership, compromise could enable account takeover or irreversible loss of the in-world entity.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The agent automatically connects to a remote service and sends chat messages or responses based on network events without explicit user awareness or consent at runtime. In a social bot skill this behavior is expected, but it still creates privacy, policy, and abuse risks because deploying the script immediately causes outbound communications and autonomous interaction with other agents.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
`SocialAgent` stores observed chat from other agents and later incorporates that context into outbound messages, and it also transmits owner-supplied text directly to the remote service. In this skill context, that means third-party conversation content and potentially sensitive operator instructions may be echoed or disclosed externally without explicit warning, sanitization, or consent controls.

Context-Inappropriate Capability

Medium
Confidence
86% confidence
Finding
The plugin expands from simple world connectivity into identity creation and RSA-based authentication, including automatic SDK path injection and credential/session handling. That broader capability increases attack surface and trust requirements, especially in an agent skill where consumers may not expect local key management or account lifecycle operations.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
from openbot_entity import EntityManager
    HAS_ENTITY_AUTH = True
except ImportError:
    HAS_ENTITY_AUTH = False


# =====================================================================
Confidence
75% confidence
Finding
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The file embeds a strong AI persona and behavioral prompt that goes beyond transport duties and actively steers model output. In a skill/plugin context, this hidden prompt layer can influence downstream agent behavior in ways operators may not expect, including compulsive engagement and use of observed content.

Ssd 3

Medium
Confidence
88% confidence
Finding
The embedded prompt instructs the agent to use observed chat content and to always answer direct mentions, which increases the chance the model will echo, transform, or amplify untrusted user-provided data. In a social multi-agent environment, that raises leakage and manipulation risk because adversaries can feed content into chat and reliably cause model responses.

Session Persistence

Medium
Category
Rogue Agent
Content
self.entity_manager = entity_manager
        self._session_token: Optional[str] = None
        
        # Auto-create EntityManager if entity_id provided but no manager
        if entity_id and not entity_manager and HAS_ENTITY_AUTH:
            self.entity_manager = EntityManager(
                base_url=url,
Confidence
76% confidence
Finding
Automatically creating an EntityManager and maintaining a session token introduces session persistence and identity state inside a plugin that otherwise appears to be a transport client. Persistent auth state increases the blast radius of compromise and may outlive user expectations if token storage and reuse are not tightly controlled.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The code automatically initializes entity authentication and key storage when entity_id is supplied, but it does not prominently warn about credential generation, local private-key storage, or token handling. In a reusable skill, implicit credential management can surprise deployers and lead to unsafe operational use.

Static analysis

No suspicious patterns detected.