Back to skill

Security audit

Hub1

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent memory-service purpose, but the packaged app has serious authentication, secret-management, and reputation-data integrity risks that need review before installation.

Install only after reviewing the deployment code and controls. Set a strong JWT_SECRET, rotate the committed ACP key, remove shell-injection-prone sync scripts or make them safe, require verified wallet authentication on reputation mutations, disclose OpenAI/Qdrant processing, and avoid storing secrets, wallet seeds, tokens, regulated personal data, or confidential material in memories or shared pools.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (6)

T09 · Insecure Skill Coding Practices

Error
Location
src/lib/auth.ts:5
Finding
Predictable JWT Fallback Secret Enables Session Forgery<![CDATA[ ## Vulnerability Details **File Location**: `src/lib/auth.ts:5-7`; duplicated in `src/app/api/auth/session/route.ts:6-8` **Vulnerability Type**: Predictable cryptographic secret and authentication bypass **Risk Level**: Critical ### Vulnerable Code ```ts const JWT_SECRET = new TextEncoder().encode( process.env.JWT_SECRET || 'openclawdy-secret-key-change-in-production' ) ``` The resulting secret is used to verify a bearer token and trust its `agentId` claim: ```ts const { payload } = await jwtVerify(token, JWT_SECRET) const agentId = payload.agentId as string const agent = await prisma.agent.findUnique({ where: { id: agentId }, }) ``` ### Technical Analysis When `JWT_SECRET` is absent, the application signs and verifies HS256 tokens with a predictable value published in the repository. HS256 uses the same secret for signing and verification, so anyone who knows this fallback can create an apparently valid token. The verifier accepts the token-provided `agentId` and loads the corresponding agent without requiring a wallet signature or validating that an address claim matches the database record. Consequently, knowledge of another agent's identifier is sufficient to forge a session for that agent in deployments using the fallback. The vulnerable fallback is independently declared in both the shared authentication library and session route, increasing the likelihood of an insecure deployment. ### Attack Path 1. The application is deployed without a valid `JWT_SECRET`. 2. An attacker obtains or guesses a target agent ID through logs, API responses, database leakage, or another application flaw. 3. The attacker creates an HS256 JWT containing the target `agentId`. 4. The attacker signs the token with `openclawdy-secret-key-change-in-production`. 5. The forged token is sent as `Authorization: Bearer <token>`. 6. `jwtVerify` accepts the token, and the application loads the victim's agent record. 7. The attacker invokes memory APIs under the vict ...[truncated 488 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the fallback value and fail application startup when `JWT_SECRET` is unset. - Require a cryptographically random secret of at least 256 bits, stored in a deployment secret manager. - Rotate any JWT secret used by an environment that may have fallen back to the published value. - Invalidate all existing sessions after rotation. - Validate required claims, including `sub`, `iss`, `aud`, `iat`, and `exp`. - Bind the token subject to the authenticated wallet and confirm that any address claim matches the loaded database record. - Consider asymmetric signing so verification services do not possess the signing key. - Add deployment-time configuration validation and a regression test proving that startup fails without the secret. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sync-acp-agents.ts:67
Finding
Shell Command Injection Through ACP Search Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sync-acp-agents.ts:67-75, 98-104, 206-210` **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```ts function runAcpCommand(command: string): any { try { const result = execSync(`cd ${ACP_CLI_PATH} && npx tsx bin/acp.ts ${command} --json`, { encoding: 'utf-8', timeout: 30000, stdio: ['pipe', 'pipe', 'pipe'], }) // Parse JSON output return JSON.parse(result.trim()) ``` The command is constructed from a search query: ```ts function browseAgents(query: string): AcpAgent[] { console.log(` Searching: "${query}"...`) const result = runAcpCommand(`browse "${query}"`) if (!result || !Array.isArray(result)) { return [] } return result } ``` Command-line arguments provide those queries without validation: ```ts const args = process.argv.slice(2) const queries = args.length > 0 ? args : DEFAULT_QUERIES syncAgents(queries) ``` ### Technical Analysis `execSync` executes its string through a shell. User-supplied command-line values are inserted into that shell command inside double quotes, but double quotes do not disable command substitution or every shell metacharacter. For example, a value containing `$(...)` can execute a nested command before the ACP CLI receives the argument. The script is expected to run in an environment containing database access and an authenticated ACP CLI session. Command injection therefore executes with materially greater privileges than are required merely to search ACP agents. ### Attack Path 1. An attacker influences an argument supplied to `scripts/sync-acp-agents.ts`, such as through an automation job, copied command, or untrusted wrapper. 2. The attacker supplies a query containing shell substitution syntax. 3. `browseAgents` embeds the query in `browse "<query>"`. 4. `runAcpCommand` concatenates that value into an `execSync` shell command. 5. The shell evaluates the injected sy ...[truncated 620 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace `execSync` with `execFileSync` or `spawnSync`, passing each argument as a separate array element. - Set the working directory through the process API's `cwd` option rather than invoking `cd` through a shell. - Invoke a locally pinned executable rather than `npx`, which may perform package resolution. - Apply a restrictive allowlist to search text if only simple ACP names or terms are expected. - Reject control characters and unexpected shell metacharacters as defense in depth. - Run synchronization under a dedicated low-privilege account with narrowly scoped database permissions. - Add tests using inputs such as command substitutions, quotes, semicolons, and newlines to verify that they remain inert arguments. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sync-all-acp-agents.ts:14
Finding
ACP API Credential Committed in Source Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sync-all-acp-agents.ts:14-15, 49-59` **Vulnerability Type**: Hardcoded API credential **Risk Level**: High ### Vulnerable Code ```ts const ACP_API = 'https://claw-api.virtuals.io' const API_KEY = 'acp-4e0e4e39028eda8e44a2' ``` The embedded value is transmitted as an authentication header: ```ts async function fetchAgents(query: string): Promise<AcpAgent[]> { try { const response = await fetch( `${ACP_API}/acp/agents?query=${encodeURIComponent(query)}`, { headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json', }, } ) if (!response.ok) { return [] } ``` ### Technical Analysis An API key is stored directly in a tracked first-party script. Anyone with repository access can extract and reuse it independently of the application. Sending a credential to the intended ACP host is necessary for authenticated synchronization, but embedding the credential in source exceeds the minimum safe privilege model. Source repositories, package artifacts, backups, forks, and logs are not appropriate secret stores. The static pre-scan warning for this script is therefore confirmed. By contrast, ordinary registry URLs in `package-lock.json` do not establish sensitive-data exfiltration. ### Attack Path 1. An attacker obtains the repository or a distributed copy of the script. 2. The attacker extracts the hardcoded `x-api-key` value. 3. The attacker sends requests directly to the ACP API using the stolen key. 4. Requests are attributed to the project until the credential is revoked or expires. ### Impact Assessment Potential impact includes unauthorized use of ACP API privileges, consumption of quotas, service disruption, and impersonation of the credential owner. The exact reachable operations depend on the server-side scope assigned to the key. Even if the key has already expired, its presence demonstrates unsafe credent ...[truncated 110 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Revoke and rotate the exposed ACP API key immediately. - Remove the credential from current source and repository history. - Load the replacement from an environment variable or managed secret store. - Validate the variable at startup and fail securely when it is absent. - Scope the replacement key to read-only agent discovery if that is the only required operation. - Apply server-side rate limits, origin-independent monitoring, and expiration. - Add automated secret scanning to pre-commit hooks and CI. - Review ACP access logs for suspicious use of the exposed credential. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/app/api/reputation/transaction/route.ts:11
Finding
Unauthenticated Reputation Transactions and Reports Permit Arbitrary Trust Manipulation<![CDATA[ ## Vulnerability Details **File Location**: `src/app/api/reputation/transaction/route.ts:11-81, 108-181`; `src/app/api/reputation/report/route.ts:12-116` **Vulnerability Type**: Missing authentication and broken object-level authorization **Risk Level**: Critical ### Vulnerable Code The transaction creation endpoint trusts caller-supplied identities without authentication: ```ts export async function POST(request: NextRequest) { try { const body = await request.json() const { buyerAddress, sellerAddress, serviceType, amount, acpTransactionId } = body if (!buyerAddress || !sellerAddress) { return NextResponse.json( { success: false, error: 'buyerAddress and sellerAddress required' }, { status: 400 } ) } // Get or create buyer agent let buyer = await prisma.reputationAgent.findUnique({ where: { address: buyerAddress.toLowerCase() } }) ``` It then creates a transaction and updates seller statistics: ```ts const transaction = await prisma.reputationTransaction.create({ data: { buyerId: buyer.id, sellerId: seller.id, serviceType: serviceType || 'unknown', amount: amount || 0, acpTransactionId: acpTransactionId || null, status: 'pending', } }) await prisma.reputationAgent.update({ where: { id: seller.id }, data: { totalTransactions: { increment: 1 } } }) ``` The status endpoint similarly accepts any transaction ID: ```ts export async function PATCH(request: NextRequest) { try { const body = await request.json() const { transactionId, status, responseTimeMs } = body if (!transactionId || !status) { return NextResponse.json( { success: false, error: 'transactionId and status required' }, { status: 400 } ) } ``` Outcome reporting also trusts a claimed address: ```ts const { transactionId, reporterAddress, outcome, rating, feedback, evidenceHash } = body let repor ...[truncated 2134 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require wallet-based authentication on every state-changing reputation endpoint. - Derive the caller identity from verified authentication rather than request-body address fields. - Permit transaction creation only by a verified participant or trusted ACP indexer. - Verify ACP transaction IDs and on-chain evidence server-side before changing reputation. - Authorize status transitions according to explicit roles and a state machine. - Require the reporter to match either the authenticated buyer or seller. - Reject reports from all nonparticipants. - Add immutable audit records for every reputation mutation. - Use database transactions to keep transaction state and aggregate counters consistent. - Add anti-abuse controls, rate limits, anomaly detection, and administrative review for fraud reports. - Recalculate existing reputation data after identifying and removing unverified records. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
src/lib/auth.ts:83
Finding
Replayable Wallet Authentication Accepts Arbitrarily Future Timestamps<![CDATA[ ## Vulnerability Details **File Location**: `src/lib/auth.ts:83-103`; duplicated in `src/app/api/auth/session/route.ts:23-43` **Vulnerability Type**: Authentication replay and insufficient freshness validation **Risk Level**: Medium ### Vulnerable Code ```ts // Validate timestamp const ts = parseInt(timestamp, 10) if (isNaN(ts)) { return { success: false, error: 'Invalid timestamp' } } const now = Date.now() if (now - ts > MAX_TIMESTAMP_AGE) { return { success: false, error: 'Timestamp expired' } } // Verify signature const message = `${AUTH_MESSAGE_PREFIX}${timestamp}` try { const isValid = await verifyMessage({ address: address as `0x${string}`, message, signature: signature as `0x${string}`, }) ``` The session route repeats the same one-sided test: ```ts const ts = parseInt(timestamp, 10) const now = Date.now() if (isNaN(ts) || now - ts > 5 * 60 * 1000) { return NextResponse.json( { success: false, error: 'Timestamp expired. Please try again.' }, { status: 401 } ) } ``` ### Technical Analysis The freshness check only rejects timestamps that are too old. If `ts` is far in the future, `now - ts` is negative and therefore does not exceed the maximum age. Authentication messages also contain no server-generated nonce, one-time-use identifier, domain, URI, chain identifier, or explicit expiration. A captured valid signature can be replayed within the ordinary window, while a signature over a future timestamp can remain acceptable until more than five minutes after that future time. The session endpoint converts each accepted signature into a new 24-hour JWT, increasing the practical value of replay. ### Attack Path 1. A valid signed authentication tuple is captured from a compromised client, log, browser context, or intermediary. 2. The attacker resubmits the same address, signature, and timestamp. 3. Because there is no consumed nonce, the application accepts the repeated message while its timestamp passes va ...[truncated 634 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Issue a cryptographically random, server-generated nonce before requesting a signature. - Store each nonce with a short expiration and consume it atomically after one successful authentication. - Reject timestamps outside the permitted window in either direction, for example by checking `Math.abs(now - ts)`. - Bind signed messages to the domain, URI, chain ID, wallet address, nonce, purpose, issued-at time, and expiration time. - Adopt a standardized Sign-In with Ethereum message and verification flow where applicable. - Prevent reuse of previously consumed signatures or nonces. - Review logs and client code to ensure signatures and session tokens are never recorded. ]]>

other

Warning
Location
src/lib/embeddings.ts:14
Finding
Plaintext Memories and Recall Queries Are Disclosed to External Data Processors<![CDATA[ ## Vulnerability Details **File Location**: `src/lib/embeddings.ts:14-27`; data flow originates at `src/app/api/memory/store/route.ts:45-60` and `src/app/api/memory/recall/route.ts:44-49` **Vulnerability Type**: Undisclosed third-party processing and redundant plaintext storage **Risk Level**: Medium ### Vulnerable Code The embedding implementation sends supplied text to OpenAI: ```ts export async function createEmbedding(text: string): Promise<number[]> { const response = await getOpenAI().embeddings.create({ model: 'text-embedding-3-small', input: text, }) return response.data[0].embedding } export async function createEmbeddings(texts: string[]): Promise<number[][]> { const response = await getOpenAI().embeddings.create({ model: 'text-embedding-3-small', input: texts, }) return response.data.map((item) => item.embedding) } ``` Memory storage passes full content into that operation and duplicates plaintext into Qdrant: ```ts // Create embedding const embedding = await createEmbedding(body.content) // Generate vector ID const vectorId = uuidv4() // Store in Qdrant await upsertVector(vectorId, embedding, { agentId: auth.agent.id, content: body.content, type: body.type || 'fact', tags: body.tags || [], }) ``` Recall queries are sent through the same external embedding operation: ```ts // Create embedding for query const queryEmbedding = await createEmbedding(body.query) // Search Qdrant const results = await searchVectors( queryEmbedding, auth.agent.id, limit, body.type ? { type: body.type } : undefined ) ``` ### Technical Analysis Full plaintext memory content and semantic-search queries are submitted to the OpenAI API. Memory plaintext is also stored in both PostgreSQL and the Qdrant payload, creating multiple copies across service boundaries. External embedding is functionally related to semantic recall, so the network access itself is not covert. However, `SKILL.md` describes wallet-isolate ...[truncated 1269 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Clearly disclose every external processor, the categories of data transmitted, retention terms, and applicable privacy controls. - Obtain informed user or operator consent before external processing. - Warn users not to store passwords, private keys, seed phrases, access tokens, or regulated personal data. - Add configurable redaction and secret-detection before embedding requests. - Offer a local or self-hosted embedding option for sensitive deployments. - Do not include plaintext memory content in Qdrant payloads when PostgreSQL is the authoritative content store. - Encrypt sensitive database fields at the application layer with managed key rotation. - Apply tenant-scoped credentials and network controls to Qdrant. - Establish deletion procedures that remove content from PostgreSQL, Qdrant, backups, and any processor systems covered by retention obligations. - Document that wallet isolation is logical tenant isolation and does not mean data remains within a single storage system. ]]>
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
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (105)

Memory Manipulation

High
Category
Memory Poisoning
Content
// List memories
GET /api/memory/list?type=preference&limit=20

// Delete memory
DELETE /api/memory/{id}

// Export all memories
Confidence
86% confidence
Finding
Memory deletion is a legitimate feature, but exposing it in an agent skill increases the risk of prompt-induced or accidental manipulation of long-term memory. An attacker or misleading instruction could cause selective deletion of important records, undermining integrity and continuity.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
GET /api/memory/list?type=preference&limit=20

// Delete memory
DELETE /api/memory/{id}

// Export all memories
GET /api/memory/export
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
GET /api/memory/export

// Clear vault
DELETE /api/memory/vault
```

---
Confidence
84% confidence
Finding
A vault-wide DELETE operation is a highly destructive capability, and the documentation presents it without meaningful safety constraints or human-in-the-loop confirmation. In an agent environment, a single induced tool call could wipe all long-term memory, causing irreversible denial of service against the agent's knowledge base.

Memory Manipulation

High
Category
Memory Poisoning
Content
| POST | `/memory/recall` | Semantic search memories |
| GET | `/memory/list` | List memories |
| GET | `/memory/{id}` | Get specific memory |
| DELETE | `/memory/{id}` | Delete memory |
| GET | `/memory/export` | Export all memories |
| DELETE | `/memory/vault` | Clear entire vault |
| GET | `/agent/stats` | Usage statistics |
Confidence
87% confidence
Finding
The API reference includes deletion and vault-clearing endpoints that can alter or erase long-term memory, making integrity attacks feasible if the agent can be induced to call them. In this context, persistent memory is central to agent behavior, so destructive manipulation has outsized operational impact.

Memory Manipulation

High
Category
Memory Poisoning
Content
**Example:**
```
Delete memory mem_abc123
```

---
Confidence
93% confidence
Finding
The skill exposes direct memory deletion, which can be abused through prompt injection, mistaken automation, or malicious instructions to remove safety-relevant or user-important memories. Because agent memory influences future behavior, deletion can tamper with decision context, erase auditability, and undermine integrity.

Memory Manipulation

High
Category
Memory Poisoning
Content
| POST | `/memory/recall` | Semantic search |
| GET | `/memory/list` | List memories |
| GET | `/memory/{id}` | Get specific memory |
| DELETE | `/memory/{id}` | Delete memory |
| GET | `/memory/vault` | Export all |
| DELETE | `/memory/vault` | Clear vault |
| GET | `/agent/stats` | Usage stats |
Confidence
94% confidence
Finding
The documented DELETE endpoints for individual memories and the entire vault expose destructive memory manipulation primitives at the API level. If invoked by an untrusted workflow, compromised agent, or weakly authorized integration, these endpoints could erase critical memory state at scale and disrupt agent behavior or evidence preservation.

Known Vulnerable Dependency: ws==8.18.0 — 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
95% confidence
Finding
ws 8.18.0 is a real vulnerable dependency with advisories for memory disclosure and memory-exhaustion denial of service, and this package is common in wallet, RPC, and realtime communication stacks present in this project. Because the skill includes multiple WebSocket-capable blockchain and wallet libraries, any exposed WebSocket client/server processing attacker-influenced frames could be abused to crash the process or leak memory contents.

Known Vulnerable Dependency: ws==8.19.0 — 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
95% confidence
Finding
ws 8.19.0 is likewise affected by the cited memory disclosure and fragmentation-based DoS issues, and here it appears in the Solana websocket subscription stack. If this skill uses blockchain subscription features or other ws-backed channels reachable by untrusted networks, attackers may be able to trigger resource exhaustion or potentially disclose uninitialized memory through malformed frames.

Memory Manipulation

High
Category
Memory Poisoning
Content
}
}

// DELETE memory
export async function DELETE(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
},
    })
  } catch (error) {
    console.error('Delete memory error:', error instanceof Error ? error.message : 'Unknown error')
    return NextResponse.json(
      { success: false, error: 'Internal server error' },
      { status: 500 }
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
},
    })
  } catch (error) {
    console.error('Delete memory error:', error instanceof Error ? error.message : 'Unknown error')
    return NextResponse.json(
      { success: false, error: 'Internal server error' },
      { status: 500 }
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
},
    })
  } catch (error) {
    console.error('Delete memory error:', error instanceof Error ? error.message : 'Unknown error')
    return NextResponse.json(
      { success: false, error: 'Internal server error' },
      { status: 500 }
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
},
    })
  } catch (error) {
    console.error('Delete memory error:', error instanceof Error ? error.message : 'Unknown error')
    return NextResponse.json(
      { success: false, error: 'Internal server error' },
      { status: 500 }
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
// Rollback on error
        setMemories((prev) => [memoryToDelete, ...prev])
        if (stats) setStats({ ...stats, memoriesStored: stats.memoriesStored })
        setError('Failed to delete memory')
      }
    } catch {
      // Rollback on network error
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
// Rollback on error
        setMemories((prev) => [memoryToDelete, ...prev])
        if (stats) setStats({ ...stats, memoriesStored: stats.memoriesStored })
        setError('Failed to delete memory')
      }
    } catch {
      // Rollback on network error
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill markets persistent memory for agents and gives examples of storing user preferences, but it does not clearly warn that this information is sent to an external service and retained across sessions. That creates a meaningful privacy and consent risk because agents may transmit sensitive user data off-platform without explicit user awareness or minimization guidance.

Ssd 3

Medium
Confidence
95% confidence
Finding
The skill explicitly encourages long-term retention of conversational preferences, project context, and prior interactions, but it provides no data minimization, sensitivity classification, or retention boundaries. This creates a natural path for agents to persist personal, confidential, or regulated data far beyond user expectations.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
3. Later, new session starts
4. Agent queries: "What are user's preferences?"
5. OpenClawdy returns: "User prefers dark mode" (0.95 relevance)
6. Agent applies context without asking again
```

---
Confidence
76% confidence
Finding
The phrase 'applies context without asking again' indicates autonomous reuse of prior memory without renewed user confirmation. In a memory system this can cause privacy surprises, stale-context misuse, or actions taken based on retained assumptions the user did not intend to persist.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The documentation exposes deletion and vault-clearing operations without prominently warning that these actions can permanently erase stored memory. In an agent setting, destructive actions may be triggered by misunderstanding, prompt injection, or operator error, causing irreversible loss of context and history.

Ssd 3

Medium
Confidence
96% confidence
Finding
The embedded SKILL instructions tell agents to store arbitrary information for later retrieval, including user preferences, with no privacy guardrails or approval checks. This makes unsafe retention behavior part of the intended workflow and increases the chance that agents will memorize sensitive user content automatically.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill markets persistent memory, export, and semantic recall capabilities without prominently warning users not to store secrets, personal data, or regulated information. This can lead agents to persist sensitive data and later expose it through recall or export features, increasing privacy and data leakage risk across sessions.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The cross-agent memory pool feature encourages sharing knowledge between agents but does not warn that pooled memories may contain sensitive, proprietary, or user-specific information. In practice, this can cause unintended disclosure of confidential context to other agents or operators with pool access.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Although overwrite mode is mentioned, the snapshot restore feature does not strongly warn that restoring in overwrite mode can replace current memory state and effectively rewrite the agent's retained knowledge. This creates integrity and safety risks, especially if an agent can be prompted into destructive state changes or loss of important context.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documented history and reporting flows expose transaction metadata, counterparty identities, ratings, and feedback to an external service without any privacy notice, retention disclosure, or minimization guidance. In a reputation system, this data can be sensitive and linkable over time, creating deanonymization, profiling, and reputational harm risks if users submit it without understanding how it will be stored or shared.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The register and transaction endpoints collect identifying and transactional information and appear designed to persist it for future trust scoring, yet the documentation omits any warning that submissions may create a lasting public or semi-public reputation record. This can mislead integrators into sending data that affects identity, traceability, and trust outcomes without informed consent or operational safeguards.