Back to skill

Security audit

Receipts Guard

Security checks for vulnerabilities and agentic risk

Overview

The skill is not deceptive, but it handles identities, agreement records, and blockchain actions with enough unsafe security gaps that it needs careful review before use.

Install only after reading the source and only if you need this identity/arbitration workflow. Prefer testnets, do not expose the HTTP server publicly without strict API keys and origin controls, do not use a funded mainnet wallet key unless you accept irreversible transactions, and avoid relying on legacy signatures or controller recovery until those verification issues are fixed.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
capture.js:1203
Finding

Forgeable Legacy Agreement Signatures Use a Public Agent Identifier as the HMAC Key

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
capture.js:3369
Finding

Identity Recovery Replaces Keys Without Verifying the Claimed Controller Proof

Content
View full analysis
', note: 'Human controller must post recovery authorization' })); process.exit(1); } ``` After a local confirmation flag, the supplied URL is merely recorded and new keys replace the existing identity keys: ```javascript const recoveryRecord = { type: 'controller_recovery', did: didDocument.id, controller: didDocument.controller, proofUrl: filters['controller-proof'], previousKeyId: didDocument.authentication?.[0], newKeyId: newKeypair.keyId, recoveredAt: new Date().toISOString() }; // Update DID document - replace all keys didDocument.verificationMethod = [{ id: `${didDocument.id}${newKeypair.keyId}`, type: "Ed25519VerificationKey2020", controller: didDocument.id, publicKeyMultibase: newKeypair.publicKeyMultibase }]; didDocument.authentication = [`${didDocument.id}${newKeypair.keyId}`]; didDocument.assertionMethod = [`${didDocument.id}${newKeypair.keyId}`]; ``` The new unencrypted private key is then made current: ```javascript const newKeyData = { keyId: newKeypair.keyId, privateKey: newKeypair.privateKey.toString('base64'), publicKeyMultibase: newKeypair.publicKeyMultibase, createdAt: newKeypair.createdAt, encrypted: false }; const keyFilePath = path.join(PRIVATE_KEY_DIR, 'key-current.json'); fs.writeFileSync(keyFilePath, JSON.stringify(newKeyData, null, 2)); try { fs.chmodSync(keyFilePath, 0o600); } catch (e) {} ``` ### Technical Analysis The code does not retrieve the controller post, verify its platform or account, compare its contents with a stored challenge, validate a cont ...[truncated 1322 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
capture.js:1381
Finding

Unvalidated Record Identifiers Permit Filesystem Path Traversal

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
capture.js:2938
Finding

DID Private Keys Are Stored as Unencrypted Base64 Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
capture.js:4383
Finding

HTTP Server Buffers Request Bodies Without a Size Limit

Content
View full analysis
{ let body = ''; req.on('data', chunk => body += chunk); req.on('end', () => { try { resolve(body ? JSON.parse(body) : {}); } catch (e) { reject(new Error('Invalid JSON body')); } }); req.on('error', reject); }); } ``` ### Technical Analysis Every POST body is concatenated into a JavaScript string until the client closes the request. There is no maximum byte count, `Content-Length` validation, streaming parser, or request timeout in this function. The per-IP rate limiter restricts request count but not request size. An authenticated client can therefore consume substantial memory with one request. Slow transmission can also hold connections and memory for an extended period. The supplied Fly.io configuration allocates only 256 MB of memory, making resource exhaustion more practical. ### Attack Path 1. Obtain a valid API key or use the locally supported DID authentication. 2. Open a POST request to a protected endpoint. 3. Send a very large JSON body, or continuously stream body data without completing the request. 4. The server repeatedly appends each chunk to the in-memory string. 5. Memory consumption and garbage-collection overhead increase until the process becomes unavailable or is terminated. ### Impact Assessment A malicious or compromised authenticated client can cause denial of service for the HTTP API. The attack may terminate the process, interrupt agreement operations, and require a service restart. No additional identity or operating-system privileges are obtained. ]]>
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is framed primarily as ERC-8004/x402/arbitration infrastructure, but it also exposes an HTTP management surface, authenticated request handling, migration utilities, and local agreement storage. In security terms, incomplete disclosure of remotely reachable functionality and state-changing endpoints can lead to incorrect trust assumptions and deployment in contexts where the operator did not realize a service API was being exposed.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The skill is framed primarily as ERC-8004/x402/arbitration infrastructure, but it also exposes an HTTP management surface, authenticated request handling, migration utilities, and local agreement storage. In security terms, incomplete disclosure of remotely reachable functionality and state-changing endpoints can lead to incorrect trust assumptions and deployment in contexts where the operator did not realize a service API was being exposed.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 724)May include surrounding context.

md
const receipts = require('./capture.js');

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

On-chain anchoring can spend funds and publish identity-linked metadata over the network, and the current flow proceeds directly once invoked. The lack of an execution-time confirmation or safe preview is dangerous because blockchain actions are irreversible, cost-bearing, and may deanonymize the agent's identity infrastructure.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.17.1 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
98% confidence
Finding

The lockfile pins transitive dependency ws to version 8.17.1, and the supplied advisories indicate that this version is affected by uninitialized memory disclosure and memory-exhaustion denial of service. In this skill’s context—autonomous agent commerce with networked payment/arbitration flows—WebSocket connectivity is plausible, so a vulnerable ws version could expose sensitive data or allow remote service disruption if any code path uses ethers/websocket transport.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
95% confidence
Finding

The report documents a real prior weakness: archived private keys were created with default 0644 permissions, making them readable by other local users on shared systems. Exposure of old private keys can undermine historical signature trust, aid impersonation where old keys remain accepted, and leak sensitive cryptographic material even if the issue is now described as fixed.

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 72)May include surrounding context.

md
**Status:** Fixed

**Description:**
Archived private keys in `~/.openclaw/receipts/identity/private/key-archive/` were created with default permissions (644), making them world-readable.

**Impact:**
Other users on a shared system could potentially read old private keys.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 79)May include surrounding context.

Fix Applied:

javascript
// In handleIdentityRotate() - added chmod after archive write
const archiveFilePath = path.join(KEY_ARCHIVE_DIR, `${currentKeyData.keyId.replace('#', '')}.json`);
fs.writeFileSync(archiveFilePath, JSON.stringify({...}, null, 2));
try {

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

Scanner excerpt · SECURITY_AUDIT.md (reported line 187)May include surrounding context.

node capture.js identity verify --signature="" --termsHash=""

Check file permissions

ls -la ~/.openclaw/receipts/identity/private/ stat -f "%Sp %OLp" ~/.openclaw/receipts/identity/private/key-current.json

text

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises operational capabilities that clearly involve shell execution, network access, and environment-variable use, but it does not declare an explicit tool/permission scope. That weakens least-privilege controls and can cause hosts or users to invoke the skill without understanding that it can access secrets, make outbound requests, or run local commands.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
90% confidence
Finding

The documentation includes an option to set RECEIPTS_ALLOWED_ORIGINS=*, which permits any origin to make browser-based cross-origin requests. Even if marked as not recommended, presenting a permissive wildcard as a supported configuration increases the likelihood of insecure deployments, especially when the service exposes authenticated state-changing endpoints.

Content

Scanner excerpt · SKILL.md (reported line 289)May include surrounding context.

Allow specific origins

export RECEIPTS_ALLOWED_ORIGINS=https://app.example.com,https://dashboard.example.com

Allow all origins (not recommended for production)

export RECEIPTS_ALLOWED_ORIGINS=*

text

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest frames the skill as implementing ERC-8004 identity, x402 payments, and arbitration protocol for agent commerce. This file goes materially beyond that by acting as a local evidence-capture and legal-risk analysis tool for ToS text, screenshots, promise capture, diffing, export, and dispute-package generation, which are not described as part of the skill's stated scope.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes protocol rails for identity, payments, and arbitration, but does not mention hosting an HTTP API/service. Adding a long-running web server with authenticated endpoints materially changes the operational capability of the skill beyond the stated protocol/tooling purpose.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · capture.js (reported line 1572)May include surrounding context.

js
});

  // Status becomes pending_confirmation (other party must confirm)
  // For simplicity, we'll auto-confirm after a grace period (in production, this would be interactive)
  agreement.status = 'pending_confirmation';
  agreement.fulfillmentClaimed = {
    by: agentId,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The programmatic capture path persists full agreement text and optional screenshot-derived data to disk automatically, which can collect sensitive contractual or personal information without a clear consent boundary. In an agent framework, this creates privacy and data-retention risk because integrations may invoke it silently at scale.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The promise capture API writes commitment text to local files without confirmation or disclosure, potentially storing sensitive negotiations, obligations, or business data. Because this is a library-style path, downstream callers may unintentionally create durable records that affect privacy, confidentiality, or legal exposure.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · capture.js (reported line 2752)May include surrounding context.

js
// Get public key from DID document (try current key first)
  const verificationMethod = didDocument.verificationMethod[0];
  if (!verificationMethod) {
    return { valid: false, error: 'No verification method in DID document' };
  }

  try {

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The controller verification flow records a user-supplied URL and marks the controller as verified without validating that the post exists, belongs to the claimed account, or contains the expected challenge. This can let an attacker self-assert recovery authority and undermine trust in the identity recovery mechanism.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code can perform live on-chain transactions using a private key from environment variables, which is a sensitive and irreversible action. In a skill context, this materially increases risk because a caller may trigger spending or identity registration without a separate approval gate beyond invoking the command.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency uses a caret range (^6.11.0), which allows newer compatible versions to be installed over time instead of a single immutable version. In a security-sensitive commerce and identity skill, this increases supply-chain risk because a compromised or breaking upstream release could be pulled in without an intentional review.

Content

Scanner excerpt · package.json (reported line 25)May include surrounding context.

json
"author": "Remaster.io",
  "license": "MIT",
  "dependencies": {
    "ethers": "^6.11.0",
    "tweetnacl": "^1.0.3"
  },
  "engines": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency uses a caret range (^1.0.3), so installs may resolve to different package versions over time. Because this skill handles identity and payment-related functionality, any unexpected upstream package change could affect cryptographic or security behavior and enlarge the supply-chain attack surface.

Content

Scanner excerpt · package.json (reported line 26)May include surrounding context.

json
"license": "MIT",
  "dependencies": {
    "ethers": "^6.11.0",
    "tweetnacl": "^1.0.3"
  },
  "engines": {
    "node": ">=18.0.0"

Static analysis

No suspicious patterns detected.