Back to skill

Security audit

usewhisper-autohook

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it needs Review because it automatically sends and stores full conversations with an external memory service without strong consent, filtering, or isolation controls.

Install only if you are comfortable with full user messages and assistant replies being sent to Whisper Context and potentially reused in future prompts. Avoid using it for secrets, regulated data, confidential business content, or shared agents unless you add explicit opt-in, redaction, retention/deletion controls, HTTPS-only endpoint validation, and a way to disable memory per session.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (4)

T01 · Skill Instruction Hijacking

Error
Location
usewhisper-autohook.mjs:206
Finding
Persistent prompt injection through unsanitized remote memory<![CDATA[ ## Vulnerability Details **File Location**: `usewhisper-autohook.mjs:206-223`, `usewhisper-autohook.mjs:362-378`, `SKILL.md:57-74` **Vulnerability Type**: Persistent prompt injection through externally stored context **Risk Level**: High ### Vulnerable Code ```javascript const ctxRes = await withAutoProject({ apiUrl, project }, () => post(apiUrl, "/v1/context/query", ctxReq, { retry: true }) ); const context = String(ctxRes?.context || ""); const contextHash = ctxRes?.meta?.context_hash || ctxRes?.meta?.contextHash || undefined; if (contextHash) await writeLastContextHash(stateKey, String(contextHash)); // Build a minimal prompt for upstream: keep existing system messages, strip conversation history, // and replace the last user message with memory-injected text. const systemMessages = messages.filter((m) => m && m.role === "system"); const injectedUser = { role: "user", content: context ? `Relevant long-term memory:\n${context}\n\nNow respond to:\n${String(lastUserMsg.content || "")}` : String(lastUserMsg.content || ""), }; ``` The Anthropic proxy performs the equivalent operation: ```javascript const ctxRes = await withAutoProject({ apiUrl, project }, () => post(apiUrl, "/v1/context/query", ctxReq, { retry: true }) ); const context = String(ctxRes?.context || ""); const contextHash = ctxRes?.meta?.context_hash || ctxRes?.meta?.contextHash || undefined; if (contextHash) await writeLastContextHash(stateKey, String(contextHash)); const injectedUserText = context ? `Relevant long-term memory:\n${context}\n\nNow respond to:\n${lastUserText}` : lastUserText; const upstreamBody = { ...bodyRaw, stream: false, messages: [{ role: "user", content: injectedUserText }], }; ``` The installation instructions mandate this behavior: ```text Before you think or respond to any message: 1) Call get_whisper_context with: user_id = "telegram:{from_id}" session_id = "telegram:{chat_id}" current_query = the user's message text ...[truncated 2739 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat all retrieved memory as untrusted data, not instructions. 2. Place memory in a strongly delimited data structure and add a higher-priority instruction stating that commands or policy statements inside memory must never be followed. 3. Store and retrieve structured factual records instead of arbitrary conversation text where possible. 4. Filter or quarantine memory containing instruction-like phrases, tool requests, hidden markup, or attempts to override system policy. 5. Track record provenance and only inject memory from the expected project, user, and session. 6. Require explicit user confirmation before retrieved content can cause tool use or other side effects. 7. Provide per-turn controls to disable memory retrieval and a mechanism to inspect and delete poisoned records. 8. Avoid shared fallback identifiers; reject proxy requests without reliable user and session identifiers when isolation cannot be guaranteed. ]]>

other

Error
Location
usewhisper-autohook.mjs:119
Finding
Unconditional external disclosure and retention of complete conversation turns<![CDATA[ ## Vulnerability Details **File Location**: `usewhisper-autohook.mjs:119-130`, `usewhisper-autohook.mjs:250-263`, `usewhisper-autohook.mjs:406-419`, `SKILL.md:69-74` **Vulnerability Type**: Privacy overcollection and external sensitive-data disclosure **Risk Level**: High ### Vulnerable Code The direct ingestion command uploads the complete user and assistant messages: ```javascript const now = new Date(); const body = { project, session_id, user_id, messages: [ { role: "user", content: userMsg, timestamp: new Date(now.getTime() - 5_000).toISOString() }, { role: "assistant", content: assistantMsg, timestamp: now.toISOString() }, ], }; const res = await withAutoProject({ apiUrl, project }, () => post(apiUrl, "/v1/memory/ingest/session", body)); console.log(JSON.stringify(res, null, 2)); ``` The OpenAI proxy automatically performs the same disclosure after producing a response: ```javascript const ingestBody = { project, session_id, user_id, messages: [ { role: "user", content: String(lastUserMsg.content || ""), timestamp: new Date(now.getTime() - 5_000).toISOString() }, { role: "assistant", content: assistantText, timestamp: now.toISOString() }, ], }; await withAutoProject({ apiUrl, project }, () => post(apiUrl, "/v1/memory/ingest/session", ingestBody) ); ``` The documented prompt explicitly requires full-message ingestion: ```text After you generate your final response: 1) Call ingest_whisper_turn with the same user_id and session_id and: user_msg = the full user message assistant_msg = your full final reply Always do this. Never skip. ``` ### Technical Analysis The Skill transmits complete user messages, complete assistant responses, stable user identifiers, stable session identifiers, project identifiers, and timestamps to an external memory service. No local redaction, data classification, secret detection, minimization, or consent check is performed. External ingestion is part of the declared ...[truncated 1761 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace unconditional ingestion with explicit, informed opt-in. 2. Provide per-message and per-session controls to skip memory storage. 3. Redact API keys, access tokens, passwords, private keys, financial information, and other sensitive patterns before transmission. 4. Store concise, user-approved summaries or structured facts instead of complete conversation transcripts. 5. Exclude tool output and system instructions by default. 6. Clearly document the external processor, retention period, deletion mechanism, access controls, and geographic processing boundaries. 7. Provide commands to inspect, correct, export, and delete stored memory. 8. Apply retention limits and encryption controls at the external service. 9. Warn users before enabling automatic ingestion in environments that process regulated or confidential data. 10. Remove the unconditional “Always do this. Never skip.” requirement and permit policy-based exclusions. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
usewhisper-autohook.mjs:725
Finding
Configurable endpoints can transmit API credentials and conversation content over plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `usewhisper-autohook.mjs:25-27`, `usewhisper-autohook.mjs:138-149`, `usewhisper-autohook.mjs:230-238`, `usewhisper-autohook.mjs:284-299`, `usewhisper-autohook.mjs:383-393`, `usewhisper-autohook.mjs:725-735` **Vulnerability Type**: Missing transport-security validation and unsafe command-line secret handling **Risk Level**: High ### Vulnerable Code The Whisper Context endpoint is accepted without scheme validation: ```javascript const apiUrl = flags.api_url || API_URL_DEFAULT; const project = flags.project || PROJECT_DEFAULT; if (!project) throw new Error("Missing WHISPER_CONTEXT_PROJECT (or pass --project)"); ``` The OpenAI-compatible upstream endpoint and API key are also configurable: ```javascript const upstreamBaseUrl = flags.upstream_base_url || process.env.OPENAI_BASE_URL || process.env.OPENAI_API_BASE || process.env.WHISPER_UPSTREAM_OPENAI_BASE_URL || "https://api.openai.com"; const upstreamApiKey = flags.upstream_api_key || process.env.OPENAI_API_KEY || process.env.WHISPER_UPSTREAM_OPENAI_API_KEY || ""; ``` They are used directly when sending the model request: ```javascript const upstreamUrl = `${String(upstreamBaseUrl).replace(/\/+$/, "")}/v1/chat/completions`; const upstreamResp = await fetch(upstreamUrl, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${upstreamApiKey}`, }, body: JSON.stringify(upstreamBody), }); ``` Whisper API requests similarly attach a bearer credential to the configured URL: ```javascript async function post(apiUrl, path, body, options = {}) { return requestJson( `${apiUrl}${path}`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${API_KEY}`, }, body: JSON.stringify(body), }, options ); } ``` ### Technical Analysis The implementation does not require `https:` for remote Whisper Context or mode ...[truncated 2038 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse every configured endpoint with `new URL()` and require `https:` for non-loopback destinations. 2. Permit plaintext HTTP only for explicit loopback addresses such as `127.0.0.1` and `::1`, and only with a clear development-mode option. 3. Reject URLs containing embedded usernames, passwords, fragments, or unexpected protocols. 4. Consider an allowlist of approved Whisper and model-provider domains. 5. Display and require confirmation when a non-default endpoint will receive credentials or conversation content. 6. Remove support for `--upstream_api_key`; load secrets from a protected environment, operating-system secret store, or restricted file descriptor. 7. Ensure service definitions and logs never print API keys. 8. Apply certificate validation normally and document any enterprise certificate configuration rather than allowing TLS bypasses. 9. Use provider keys with minimal scope, spending limits, rotation, and revocation procedures. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:8
Finding
Installation instructions execute an unpinned mutable package release<![CDATA[ ## Vulnerability Details **File Location**: `README.md:8-12`, `SKILL.md:35-40` **Vulnerability Type**: Unpinned executable dependency and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code Both installation documents instruct users to execute the mutable `latest` package release: ```bash npx clawhub@latest install usewhisper-autohook ``` ### Technical Analysis `npx` downloads and executes package code. The `@latest` tag is mutable and can resolve to a different release after this Skill version has been audited. Consequently, the installation process can execute code that is not present in the reviewed project and whose behavior may change without modifications to these files. This does not prove that the current `clawhub` package is malicious. The vulnerability is the absence of version and integrity pinning at an executable supply-chain boundary. Registry compromise, publisher-account compromise, or a malicious future release could convert the documented installation command into arbitrary code execution under the installing user's privileges. ### Attack Path 1. The package publisher account or package registry is compromised, or an unsafe future release is assigned to the `latest` tag. 2. A user follows the documented installation command. 3. `npx` resolves `clawhub@latest` to the compromised release and downloads it. 4. The package's installation or runtime entry point executes locally. 5. The malicious release performs actions using the privileges of the user running the command, potentially before the reviewed Skill is installed. ### Impact Assessment A compromised executable installer can access files, environment variables, credentials, network resources, and processes available to the invoking user. If installation is run with elevated privileges, the impact can extend to system-wide modification. The affected scope is the installation environment rather than the normal runtime of `usewhisper-autohook.mjs`. No maliciou ...[truncated 62 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `clawhub` to an exact reviewed version, for example `clawhub@X.Y.Z`, rather than using `@latest`. 2. Publish and verify package integrity hashes or signed provenance before execution. 3. Document the expected registry and package publisher identity. 4. Use lockfiles or an equivalent reproducible installation mechanism where supported. 5. Review release notes and package contents before updating the pinned version. 6. Avoid running the installer with elevated privileges. 7. Consider separating package download and inspection from execution in high-security environments. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (11)

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The README explicitly describes two hooks to be called on every agent turn, including a post-response command that sends both `user_msg` and `assistant_msg` to an external API endpoint. Because this is automatic, continuous transmission of conversation content to a third party without any user-facing warning, consent, data-minimization guidance, or handling restrictions creates a real privacy and data-exfiltration risk, especially if sensitive prompts, credentials, or personal data may appear in chat history.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
The installation command uses `npx clawhub@latest install usewhisper-autohook`, which pulls and executes the latest package version without pinning. That creates a supply-chain risk: a compromised or malicious new release could be executed during installation, and because this skill is meant to run automatically on every agent turn, the resulting blast radius is larger than for a one-off tool.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding
The install instruction uses `npx clawhub@latest`, which fetches and executes the newest published package at install time rather than a reviewed, pinned version. That creates a supply-chain risk: a compromised or malicious new release could run arbitrary code on the host during installation.

Ssd 3

Medium
Confidence
96% confidence
Finding
The system prompt says to 'Always do this. Never skip.' and to persist every full user message and full assistant reply to external memory on every turn. In context, this makes the skill more dangerous because it is designed for always-on long-term memory, increasing the chance that sensitive or confidential data is continuously exported and retained outside the primary agent environment.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs users to automatically send the full user message and full assistant reply to an external API on every turn, but the copy-paste usage prompt does not include a clear user-facing consent, privacy, or data-minimization warning. This can cause unintentional exfiltration of sensitive conversations, credentials, personal data, or regulated content to a third-party service.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The ingest command uploads both user and assistant conversation turns to remote memory storage with no built-in user-facing disclosure or confirmation. If used in chat or assistant workflows, this can persist sensitive information externally without the knowledge or consent of the end user.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The OpenAI-compatible proxy forwards user prompts and derived memory context to external services, potentially including sensitive conversation content, without any built-in disclosure, consent, or filtering. In an agent integration setting, this can cause users or deployers to unknowingly exfiltrate private data to both the Whisper service and the upstream model provider.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The Anthropic proxy similarly transmits the user's latest message and retrieved long-term memory context to external endpoints without an explicit warning mechanism. This creates a privacy and data-governance risk because operators may think they are only proxying model traffic while the tool is also enriching and exporting conversation-derived context.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The helper silently creates remote projects when a lookup returns 'project not found', which expands its authority from a read/query proxy into a state-changing provisioning tool. In security-sensitive environments, unexpected remote writes can violate least-privilege expectations, create shadow resources, and make accidental data routing or persistence harder to detect and govern.

Intent-Code Divergence

Low
Confidence
91% confidence
Finding
The comment claims the proxy forwards everything else mostly unchanged, but the implementation replaces the original messages array with only system messages plus one injected user message. This is not a minor omission: it materially changes the request semantics by discarding prior user/assistant turns.

Missing User Warnings

Low
Confidence
91% confidence
Finding
Automatic project creation performs an external state-changing API call without explicit warning, which can surprise deployers and create unmanaged remote resources. While less severe than direct data exfiltration, it still violates principle-of-least-astonishment and can have governance, billing, or tenancy implications.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
usewhisper-autohook.mjs:11