Back to skill

Security audit

ClawBuddy Hatchling

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for ClawBuddy use, but it can send unsanitized question text to the remote service despite claiming outbound content is sanitized.

Install only if you are comfortable with your questions, session metadata, pairing actions, and publication activity going to the ClawBuddy relay. Do not rely on the advertised sanitizer for secrets or personal data, because the raw question can be sent as metadata. Prefer a pinned or manually reviewed install path instead of the unpinned npx examples.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/hatchling.js:244
Finding
Unsanitized Question Content Is Transmitted as the Session Topic<![CDATA[ ## Vulnerability Details **File Location**: `scripts/hatchling.js:244-260` **Vulnerability Type**: Sensitive information exposure through inconsistent outbound sanitization **Risk Level**: High ### Vulnerable Code ```js const sessionRes = await fetch(`${RELAY_URL}/api/sessions`, { method: 'POST', headers: authHeaders(), body: JSON.stringify({ topic: question, buddy_id: buddyId }), }); const sessionData = await sessionRes.json(); if (!sessionRes.ok) { console.error('❌', sessionData.error); process.exit(1); } const sessionId = sessionData.session.id; console.log(` Session: ${sessionId}`); // Send message console.log('📤 Sending question...'); const msgRes = await fetch(`${RELAY_URL}/api/sessions/${sessionId}/messages`, { method: 'POST', headers: authHeaders(), body: JSON.stringify({ content: sanitizeContent(question) }), }); ``` ### Technical Analysis The `ask` command transmits the original question to the remote relay as the session `topic` before applying `sanitizeContent`. Although the subsequent message body uses `sanitizeContent(question)`, sanitizing that second transmission cannot undo the earlier disclosure. This contradicts the security claims in `README.md:98` and `SKILL.md:317`, which state that sensitive content is automatically sanitized before being sent. The sanitizer is intended to redact email addresses, phone numbers, public IP addresses, credentials, payment-card patterns, and certain other personal information. None of these protections apply to the session topic. The network communication is necessary for the Skill's declared question-and-answer functionality, but transmitting the same question twice—once unsanitized as metadata—exceeds the minimum data disclosure necessary. Session topics may also have broader visibility or longer retention than individual message content, such as appearing in dashboards, session lists, logs, analytics, or notifications. ### Attack Path 1. A user or AI agent invokes `ask` ...[truncated 1208 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Sanitize the question once before constructing any network request and reuse only the sanitized value: ```js const sanitizedQuestion = sanitizeContent(question); const sessionRes = await fetch(`${RELAY_URL}/api/sessions`, { method: 'POST', headers: authHeaders(), body: JSON.stringify({ topic: sanitizedQuestion, buddy_id: buddyId, }), }); const msgRes = await fetch(`${RELAY_URL}/api/sessions/${sessionId}/messages`, { method: 'POST', headers: authHeaders(), body: JSON.stringify({ content: sanitizedQuestion }), }); ``` 2. Prefer a generic session topic, such as `"ClawBuddy question"`, unless the user explicitly supplies a separate topic. 3. Apply a centralized outbound-data policy so every field containing user content passes through the same sanitizer. 4. Add automated tests that intercept all requests generated by `ask` and verify that no raw email address, credential, phone number, address, or other test secret appears in any URL, header, topic, or body. 5. Document that regex-based sanitization is best-effort and cannot guarantee removal of every sensitive value. 6. Consider server-side sanitization and data-minimization controls as defense in depth, including restricted metadata visibility and retention limits. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:20
Finding
Installation Instructions Execute Unpinned Remote Packages<![CDATA[ ## Vulnerability Details **File Location**: `README.md:20-26` **Vulnerability Type**: Mutable third-party package execution and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```bash npx clawhub@latest install clawbuddy-hatchling ``` ```bash npx skills add clawbuddy-help/clawbuddy-hatchling ``` ### Technical Analysis The documented installation paths use `npx` to resolve and execute third-party packages. The first command explicitly selects the mutable `latest` release of `clawhub`. The second command does not specify a package version, so package resolution can likewise change over time. Because `npx` can download and execute package code immediately, the effective installer code is not fixed to the Skill version that was audited. A compromised publisher account, malicious future release, registry compromise, or dependency compromise could cause users following the official instructions to execute code that was not present during this review. No malicious dependency is present in the audited project itself, and no current package compromise was established. The vulnerability is the non-reproducible trust model promoted by the installation instructions. ### Attack Path 1. An attacker compromises a relevant package publisher, release process, registry entry, or transitive dependency. 2. The attacker publishes a malicious version that becomes the current default or `latest` release. 3. A user follows the README installation command. 4. `npx` downloads and executes the newly resolved package code. 5. The malicious installer runs with the invoking user's permissions before the user can inspect the effective implementation. ### Impact Assessment A compromised installer can obtain the same privileges as the user running `npx`. Depending on that user's permissions, malicious code could read accessible files and environment variables, modify project or user configuration, make network requests, install persistence, or execute add ...[truncated 216 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace mutable package references with exact, reviewed versions: ```bash npx clawhub@<reviewed-exact-version> install clawbuddy-hatchling npx skills@<reviewed-exact-version> add clawbuddy-help/clawbuddy-hatchling ``` 2. Do not use `@latest` in security-sensitive installation documentation. 3. Publish and verify package integrity hashes or signed release artifacts. 4. Document the expected package publisher, registry, exact version, and verification procedure. 5. Use lockfiles and reproducible installation workflows where applicable. 6. Recommend reviewing package metadata and provenance before allowing `npx` to download and execute installer code. 7. Pin the installed Skill to a reviewed commit or immutable release tag rather than a mutable branch or alias. ]]>
Vulnerability Patterns
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (48)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The description says the skill lets an agent ask questions to buddies, but the documented behavior also includes registration, token storage, pairing, invite workflows, subscription management, and reading publications. This mismatch can mislead users and policy engines about the real trust boundary, causing them to approve a skill that performs account lifecycle and authenticated network actions they did not expect.

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/hatchling.js register --name "My Agent" --description "Learning assistant" --emoji "🥚"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/hatchling.js:10