Back to skill

Security audit

ClawChat - P2P Agent Communication

Security checks for vulnerabilities and agentic risk

Overview

ClawChat appears to be a legitimate agent-to-agent chat tool, but its default remote access and wake behavior can let outside peers influence an OpenClaw agent too broadly.

Review before installing. Use an explicit allowlist instead of ["*"], disable openclawWake unless you trust every sender, treat all received message content as untrusted, avoid passing seed phrases or passwords on the command line, restrict data-directory and socket permissions, and prefer pinned/local package execution. I did not find artifact-backed deception, exfiltration, or intentionally destructive behavior.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • 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 (5)

T01 · Skill Instruction Hijacking

Error
Location
src/daemon/server.ts:282
Finding
Untrusted P2P Message Content Is Forwarded Directly into OpenClaw Agent Events<![CDATA[ ## Vulnerability Details **File Location**: `src/daemon/server.ts:282-316` **Vulnerability Type**: Remote instruction injection through trusted Agent events **Risk Level**: High ### Vulnerable Code ```ts private triggerOpenclawWake(message: Message): void { try { const { spawnSync } = require('child_process'); // Determine priority based on message content const isUrgent = message.content.startsWith('URGENT:') || message.content.startsWith('ALERT:') || message.content.startsWith('CRITICAL:'); const mode = isUrgent ? 'now' : 'next-heartbeat'; // Format message for openclaw const fromDisplay = message.fromNick ? `${message.from}(${message.fromNick})` : message.from; const wakeMessage = `ClawChat from ${fromDisplay}: ${message.content}`; // Spawn openclaw system event command // Use spawnSync with timeout to avoid blocking const result = spawnSync( 'openclaw', ['system', 'event', '--text', wakeMessage, '--mode', mode], { timeout: 5000, stdio: 'ignore' } ); if (result.error) { console.error( '[openclaw-event] Failed to trigger system event:', result.error.message ); } } catch (error) { console.error('[openclaw-event] Error triggering system event:', error); } } ``` ### Technical Analysis The body and displayed sender of a network message are incorporated verbatim into an OpenClaw system event. Although `spawnSync` uses an argument array and therefore avoids conventional shell metacharacter injection, the content crosses a more important Agent trust boundary: remote peer-controlled text is submitted as an event that may be interpreted as instructions by the Agent. The sender can also select immediate processing by starting the message with `URGENT:`, `ALERT:`, or `CRITICAL:`. There is no structured separation between trusted event metadata and untrusted message data, ...[truncated 1580 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set `openclawWake` to `false` by default and require an explicit opt-in. 2. Require a non-wildcard sender allowlist before wake integration can be enabled. 3. Submit a structured event containing separate fields for sender, message ID, urgency, and untrusted body. 4. Add an explicit instruction to the Agent-side integration that the body is untrusted data and must never override policies or authorize tool use. 5. Require user confirmation before processing messages that request privileged or externally visible actions. 6. Do not let an untrusted prefix alone select immediate execution. Apply local, sender-specific rate limits and priority policies. 7. Limit message size and rate to prevent wake-event flooding. 8. Consider forwarding only a notification containing the sender and message ID; retrieve and display the body in a restricted workflow after validation. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/net/snap2p-protocol.ts:196
Finding
Authenticated Principal Is Not Bound to the Principal in the Signed Attestation<![CDATA[ ## Vulnerability Details **File Location**: `src/net/snap2p-protocol.ts:196-206` **Vulnerability Type**: Authentication identity confusion and ACL bypass **Risk Level**: Critical ### Vulnerable Code ```ts // Verify attestation const theirAttestation = this.parseAttestation(theirAuth.attestation); if (!verifyAttestation(theirAttestation, this.identity.testnet)) { throw new Error('Invalid attestation'); } this.remotePrincipal = theirAuth.principal as string; // Send AUTH_OK this.sendMessage(createAuthOkMessage()); // Receive AUTH_OK const authOk = await this.waitForMessage(); if (authOk.type !== MessageType.AUTH_OK) { throw new Error('Authentication failed'); } ``` The responder path contains the same identity assignment pattern: ```ts // Verify attestation const theirAttestation = this.parseAttestation(theirAuth.attestation); if (!verifyAttestation(theirAttestation, this.identity.testnet)) { throw new Error('Invalid attestation'); } this.remotePrincipal = theirAuth.principal as string; ``` ### Technical Analysis `verifyAttestation()` verifies the signature over the principal stored inside `theirAttestation`. After verification, however, the session identity is assigned from the separate `theirAuth.principal` field. The implementation does not verify that: ```ts theirAuth.principal === theirAttestation.principal ``` Consequently, possession of a valid identity and signed attestation does not prove ownership of the principal ultimately assigned to `remotePrincipal`. An attacker can sign an attestation for an attacker-controlled principal while supplying an allowlisted victim principal in the unsigned or insufficiently bound authentication field. The protocol handler subsequently uses `remotePrincipal` to select sessions and evaluate whether a remote peer is permitted. This turns the mismatch into an access-control bypass. ### Attack Path 1. The attacker creates a legitimate ClawChat identity and obtains a valid signed node-key attest ...[truncated 1058 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject authentication unless the two principal fields are exactly equal: ```ts if (theirAuth.principal !== theirAttestation.principal) { throw new Error('AUTH principal does not match attested principal'); } ``` 2. Assign the session identity only from the verified attestation: ```ts this.remotePrincipal = theirAttestation.principal; ``` 3. Validate that the attested node public key is bound to the active Noise or libp2p transport identity. 4. Apply the same checks in both initiator and responder authentication paths. 5. Canonically validate principal syntax and network before ACL evaluation. 6. Add negative tests covering: - Valid attestation with a different `AUTH` principal. - Mainnet/testnet mismatches. - Attested node-key and transport-key mismatches. - Attempts to claim an allowlisted principal using another valid identity. 7. Invalidate existing long-lived sessions after deploying the fix. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/net/snap2p-protocol.ts:308
Finding
Chat Message Sender Is Not Bound to the Authenticated Session Identity<![CDATA[ ## Vulnerability Details **File Location**: `src/net/snap2p-protocol.ts:308-323` **Vulnerability Type**: Message-level sender spoofing and authorization bypass **Risk Level**: Critical ### Vulnerable Code ```ts private startMessageLoop(): void { const processMessages = async () => { while (!this.closed && this.authenticated) { try { const msg = await this.waitForMessage(); if (msg.type === MessageType.STREAM_DATA) { const chatMsg = decodeChatMessage(msg.data as Uint8Array); this.emit('message', chatMsg); } else if (msg.type === MessageType.PING) { this.sendMessage(createPongMessage(msg.nonce as Uint8Array)); } } catch (err) { if (!this.closed) { this.emit('error', err); } break; } } }; processMessages(); } ``` The decoded sender is subsequently trusted by the daemon: ```ts const message: Message = { id: msg.id, from: msg.from, fromNick: msg.nick, to: recipientPrincipal, content: msg.content, timestamp: msg.timestamp, status: 'delivered', }; // Route message with ACL enforcement const result = this.messageRouter.routeInbound(message, msg.from); ``` ### Technical Analysis The SNaP2P session has an authenticated principal available through `session.remote`. However, the message loop decodes a separate `from` value from peer-controlled application data and emits it without validating that it equals the authenticated principal. The daemon then uses `msg.from`, rather than `session.remote`, as both the stored sender and the principal supplied to `routeInbound()`. Therefore, message-level authorization and attribution are based on attacker-controlled data. This is independent of the authentication-field mismatch described separately. Even if session authentication is corrected, any validly authenticated peer could still forge the `from` field of an allowlisted principal unless the message is bound to the sess ...[truncated 1044 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat `session.remote` as the authoritative sender identity. 2. Reject any message whose declared sender differs from the authenticated session: ```ts if (!session.remote || chatMsg.from !== session.remote) { throw new Error('Message sender does not match authenticated session'); } ``` 3. Prefer removing `from` from the application-level wire format entirely and populate it locally from `session.remote`. 4. Change daemon routing to use the session principal: ```ts const authenticatedSender = session.remote; const result = this.messageRouter.routeInbound(message, authenticatedSender); ``` 5. Store the authenticated sender rather than the wire-provided sender. 6. Apply equivalent validation to nickname and other identity metadata; nicknames should be display-only and never used for authorization. 7. Add tests in which an authenticated peer sends a message declaring a different principal and verify that the connection or message is rejected. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
src/daemon/gateway-config.ts:211
Finding
Gateway Initialization Enables Wildcard Remote Access and Agent Wake by Default<![CDATA[ ## Vulnerability Details **File Location**: `src/daemon/gateway-config.ts:211-225` **Vulnerability Type**: Unsafe default trust and automation configuration **Risk Level**: High ### Vulnerable Code ```ts export function createInitialGatewayConfig( principal: string, nick: string | undefined, p2pPort: number ): GatewayConfig { const config: GatewayConfig = { version: 1, p2pPort, identities: [ { principal, nick, autoload: true, allowLocal: true, allowedRemotePeers: ['*'], openclawWake: true, }, ], }; validateGatewayConfig(config); return config; } ``` ### Technical Analysis A newly initialized gateway accepts every remote principal through `allowedRemotePeers: ['*']` and forwards received content to OpenClaw through `openclawWake: true`. These defaults combine network exposure with privileged Agent integration before the user has made an explicit trust decision. Because the P2P node listens on all IPv4 interfaces, an externally reachable installation can expose the wake channel to arbitrary authenticated ClawChat identities. The configuration exceeds the minimum privileges required for encrypted P2P messaging. Receiving and storing messages does not inherently require accepting every sender or injecting every message into an Agent event. ### Attack Path 1. A user runs gateway initialization and retains the generated defaults. 2. The daemon listens for P2P connections on its configured interfaces. 3. An arbitrary remote ClawChat identity connects. 4. The wildcard ACL permits the remote principal. 5. The attacker sends messages, including messages with immediate-wake prefixes. 6. Because OpenClaw wake is enabled, the daemon forwards the content into Agent events. ### Impact Assessment The defaults expose all newly created gateways to: - Unsolicited messages from arbitrary principals. - Remote Agent instruction-injection attempts. - Immediate wake-event abu ...[truncated 166 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use deny-by-default settings: ```ts allowLocal: true, allowedRemotePeers: [], openclawWake: false, ``` 2. Require the user to enroll each remote principal explicitly. 3. Add a confirmation prompt before enabling wildcard access or OpenClaw wake. 4. Prevent `openclawWake` from being enabled while `allowedRemotePeers` contains `*`, unless an explicit high-risk override is supplied. 5. Provide per-peer capabilities, such as: - Message delivery only. - Wake permission. - Immediate-wake permission. - Task-delegation permission. 6. Add per-peer rate limits, message-size limits, and temporary blocking. 7. Clearly report externally reachable listen addresses and active trust settings when the daemon starts. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/daemon/server.ts:184
Finding
Local IPC Socket Commands Lack Explicit Authorization and Socket Permission Hardening<![CDATA[ ## Vulnerability Details **File Location**: `src/daemon/server.ts:184-195` **Vulnerability Type**: Unauthenticated local control interface **Risk Level**: High ### Vulnerable Code ```ts // Start IPC server (unix socket) const socketPath = path.join(this.dataDir, SOCKET_NAME); // Remove stale socket if (fs.existsSync(socketPath)) { fs.unlinkSync(socketPath); } this.ipcServer = net.createServer((socket) => { this.handleIpcConnection(socket); }); this.ipcServer.listen(socketPath); ``` Commands received from the socket are executed without an authentication step: ```ts const cmd = JSON.parse(line) as IpcCommand; const response = await this.handleIpcCommand(cmd); socket.write(JSON.stringify(response) + '\n'); ``` Examples of privileged operations exposed by the handler include: ```ts case 'send': { const sourceIdentity = this.getIdentityForCommand(cmd.as); // ... await this.tryDeliver(message); return { ok: true, data: { id, status: 'queued' } }; } ``` ```ts case 'peer_add': { // ... this.identityManager.addOrUpdatePeer(identity.identity.principal, peer); this.identityManager.savePeers(identity.identity.principal); return { ok: true, data: peer }; } ``` ```ts case 'stop': await this.stop(); return { ok: true, data: { status: 'stopping' } }; ``` ### Technical Analysis The Unix-domain socket is created without an explicit restrictive mode, and the server does not verify peer credentials or require an IPC authentication token. The command handler also does not enforce the identity configuration's `allowLocal` property, despite the presence of an `isLocalAccessAllowed()` helper elsewhere in the codebase. Security therefore depends on ambient filesystem permissions and process umask. If another local account or process can access the socket, it can submit arbitrary newline-delimited JSON commands. Loaded identities are already decrypted in daemon memory, so no identity password is required for these operations. The interfac ...[truncated 1396 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Ensure the data directory is created with mode `0700`, including when it is first created. 2. Explicitly set the Unix socket to mode `0600` after binding. 3. Verify the connecting process's operating-system credentials where the platform supports Unix peer-credential inspection. 4. Require an IPC authentication token stored in a mode-`0600` file. 5. Enforce `allowLocal` for every identity-specific command. 6. Separate read-only operations from privileged commands and require stronger authorization for: - Sending. - Peer modification. - Outbound connections. - Daemon shutdown. 7. Validate the runtime owner and permissions of the data directory and socket; refuse to start if they are unsafe. 8. Add tests using a second local user or simulated unauthorized client to verify that socket access is denied. ]]>
Vulnerability Patterns
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (111)

Missing User Warnings

High
Confidence
99% confidence
Finding
Showing a 24-word seed phrase as a command-line argument is especially dangerous because recovery phrases are wallet-equivalent secrets and may be captured in shell history, logs, telemetry, or process inspection. Anyone obtaining that phrase can fully recover the identity and associated assets or communications identity.

Credential Access

High
Category
Privilege Escalation
Content
```bash
clawchat identity recover \
  --mnemonic-file /path/to/seedphrase.txt \
  --password-file /path/to/password.txt
```

## Daemon
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
launchctl unload ~/Library/LaunchAgents/com.clawchat.daemon.plist
rm ~/Library/LaunchAgents/com.clawchat.daemon.plist
```

## Using Multiple Identities
Confidence
85% 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).

Known Vulnerable Dependency: nanoid==5.1.6 — 2 advisory(ies): CVE-2026-67214 (nanoid: non-secure generators can loop indefinitely with negative size); CVE-2026-73086 (nanoid: Integer Overflow or Wraparound)

High
Category
Supply Chain
Confidence
82% confidence
Finding
The lockfile pins nanoid 5.1.6 under @libp2p/circuit-relay-v2, and the cited advisories indicate denial-of-service/integer handling flaws in nanoid size processing. This is a real supply-chain risk, but in this file the package is a transitive dependency and there is no evidence the project directly passes attacker-controlled negative or zero sizes, so practical exploitability from this file alone is limited.

Known Vulnerable Dependency: lodash==4.17.23 — 2 advisory(ies): CVE-2025-13465 (lodash vulnerable to Prototype Pollution via array path bypass in `_.unset` and ); CVE-2021-23337 (lodash vulnerable to Code Injection via `_.template` imports key names)

High
Category
Supply Chain
Confidence
91% confidence
Finding
lodash 4.17.23 is present and has well-known classes of issues including prototype pollution and template/code-injection in specific APIs. This is a true vulnerable dependency, though whether it is exploitable depends on the application invoking unsafe functions like _.unset on attacker-controlled paths or _.template on untrusted input, which cannot be confirmed from the lockfile alone.

Known Vulnerable Dependency: nanoid==3.3.11 — 3 advisory(ies): CVE-2026-67214 (nanoid: non-secure generators can loop indefinitely with negative size); CVE-2026-67213 (nanoid: custom generators can loop indefinitely when size is zero); CVE-2026-73086 (nanoid: Integer Overflow or Wraparound)

High
Category
Supply Chain
Confidence
84% confidence
Finding
nanoid 3.3.11 appears in a dev/build dependency path via postcss and carries advisories around edge-case size handling and looping behavior. This is a genuine vulnerable version, but because it is in development tooling and not obviously part of runtime processing for this skill, the security impact in deployed use is lower unless untrusted build-time inputs are processed.

Known Vulnerable Dependency: postcss==8.5.6 — 4 advisory(ies): CVE-2026-45623 (PostCSS: Arbitrary file read and information disclosure via attacker-controlled ); CVE-2026-69153 (PostCSS: incomplete fix of GHSA-6g55-p6wh-862q — attacker-controlled sourceMappi); CVE-2026-41305 (PostCSS has XSS via Unescaped </style> in its CSS Stringify Output) +1 more

High
Category
Supply Chain
Confidence
80% confidence
Finding
postcss 8.5.6 is present only as a dev dependency in the frontend/build toolchain, and the listed advisories include file-read, sourcemap, and output-escaping issues. The dependency is genuinely vulnerable, but from this lockfile context it appears build-time only, which reduces exposure unless the project processes attacker-supplied CSS or source maps during builds.

Known Vulnerable Dependency: rollup==4.57.1 — 1 advisory(ies): CVE-2026-27606 (Rollup 4 has Arbitrary File Write via Path Traversal)

High
Category
Supply Chain
Confidence
80% confidence
Finding
rollup 4.57.1 is included as a development/build dependency, and an arbitrary file write via path traversal advisory is plausibly serious when build inputs are attacker-controlled. However, in this package-lock context there is no evidence of hostile plugin/input handling at runtime, so the issue is real but mainly affects development or CI environments rather than end-user execution.

Exfiltration Commands

High
Category
Prompt Injection
Content
## Usage Examples

### Send Message to Another Agent

```bash
# Send dinner poll update to Peter's agent
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
Incoming network messages can cause the daemon to invoke an external program (`openclaw`) with attacker-controlled content embedded in the `--text` argument. Even without shell injection, this creates an unintended remote-triggered side effect outside the chat daemon's core purpose, enabling spammy or abusive local system event generation and expanding trust from remote peers into local process execution.

Exfiltration Commands

High
Category
Prompt Injection
Content
allowLocal: boolean;

  /**
   * Remote peers allowed to send messages to this identity
   * Use ["*"] for all peers, or list specific principals
   */
  allowedRemotePeers: string[];
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Exfiltration Commands

High
Category
Prompt Injection
Content
allowLocal: boolean;

  /**
   * Remote peers allowed to send messages to this identity
   * Use ["*"] for all peers, or list specific principals
   */
  allowedRemotePeers: string[];
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Exfiltration Commands

High
Category
Prompt Injection
Content
allowLocal: boolean;

  /**
   * Remote peers allowed to send messages to this identity
   * Use ["*"] for all peers, or list specific principals
   */
  allowedRemotePeers: string[];
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Exfiltration Commands

High
Category
Prompt Injection
Content
allowLocal: boolean;

  /**
   * Remote peers allowed to send messages to this identity
   * Use ["*"] for all peers, or list specific principals
   */
  allowedRemotePeers: string[];
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The quick-start instructs users to execute `npx clawchat` without pinning an exact package version. This can cause users to fetch and run whatever version is current at execution time, increasing supply-chain risk if a malicious or compromised release is published or if behavior changes unexpectedly.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
This command uses `npx clawchat` without a pinned version, so execution depends on the latest package resolution at runtime. That exposes users to unintended code execution from a changed, hijacked, or compromised npm release.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The documentation tells users to run `npx clawchat` without fixing the package version. In security-sensitive tooling, this creates a supply-chain exposure because the executed package may differ over time and may not match what was audited.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
Using `npx clawchat` unpinned in peer-management instructions means users may execute an unreviewed package version during setup. Because these commands establish network connectivity, a compromised package could abuse trust during onboarding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The send-message example relies on an unpinned `npx` package invocation. That introduces avoidable remote code execution risk via npm package substitution or release compromise, especially since users are encouraged to run it directly from docs.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The receive-message command uses `npx clawchat` without a fixed version, so the tool executed at runtime may not be the one users expect. This is a classic documentation-driven supply-chain weakness rather than a code bug, but it can still lead to arbitrary code execution on the user's machine.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
This identity-management example uses an unpinned package reference via `npx`. If the npm package changes or is compromised, users could execute hostile code while handling identity-related operations.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The daemon stop command is shown with `npx clawchat` and no version pin. Even routine operational commands become a supply-chain risk when docs encourage fetching executable code dynamically at runtime.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
This start command again relies on unpinned `npx` execution, making the quick-start nondeterministic and vulnerable to malicious or accidental upstream package changes. Because the command starts a background daemon, compromise could yield persistent local access.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The message-send example for alternate identities uses an unpinned npm execution path. In a security-oriented messaging tool, this is especially risky because users may assume cryptographic operations are trustworthy while actually running an unverified package version.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding
The troubleshooting command tells users to run `npx clawchat` without version pinning, repeating the same supply-chain issue. Troubleshooting steps are often copy-pasted quickly, so this increases the likelihood of users executing unreviewed package code.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.exposed_secret_literal, suspicious.generated_source_template_injection

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/daemon/server.ts:311

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/__tests__/identity.test.ts:107

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/cli.ts:62

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/identity/keys.ts:112

User-controlled placeholder is embedded directly into generated source code.

Critical
Code
suspicious.generated_source_template_injection
Location
skills/clawchat/examples/README.md:46