T09 · Insecure Skill Coding Practices
- 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
Security audit
Security checks for vulnerabilities and agentic risk
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.
capture.js:1203Forgeable Legacy Agreement Signatures Use a Public Agent Identifier as the HMAC Key
capture.js:3369Identity Recovery Replaces Keys Without Verifying the Claimed Controller Proof
capture.js:1381Unvalidated Record Identifiers Permit Filesystem Path Traversal
capture.js:2938DID Private Keys Are Stored as Unencrypted Base64 Data
capture.js:4383HTTP Server Buffers Request Bodies Without a Size Limit
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.
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.
Referenced artifact was not completely inspected
const receipts = require('./capture.js');
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.
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.
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.
**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.
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.
Fix Applied:
// 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 {
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.
node capture.js identity verify --signature="" --termsHash=""
ls -la ~/.openclaw/receipts/identity/private/ stat -f "%Sp %OLp" ~/.openclaw/receipts/identity/private/key-current.json
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.
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.
export RECEIPTS_ALLOWED_ORIGINS=https://app.example.com,https://dashboard.example.com
export RECEIPTS_ALLOWED_ORIGINS=*
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.
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.
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.
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.
});
// 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,
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.
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.
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.
// 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 {
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.
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.
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.
"author": "Remaster.io",
"license": "MIT",
"dependencies": {
"ethers": "^6.11.0",
"tweetnacl": "^1.0.3"
},
"engines": {
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.
"license": "MIT",
"dependencies": {
"ethers": "^6.11.0",
"tweetnacl": "^1.0.3"
},
"engines": {
"node": ">=18.0.0"
No suspicious patterns detected.