Back to skill

Security audit

whatsappVoiceOpenSkill

Security checks for vulnerabilities and agentic risk

Overview

This skill broadly matches its WhatsApp voice-bot purpose, but it has serious implementation and privacy risks that should be reviewed before installation.

Review and patch the command execution, temp-file handling, and transcript logging before running this skill on real WhatsApp messages. Only run the listener for opted-in users, restrict the inbound directory and process privileges, avoid physical-device actions without sender verification and confirmation, and install reviewed pinned dependencies.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/voice-processor.js:34
Finding
Shell Command Injection Through Unsafe Audio Path Interpolation## Vulnerability Details **File Location**: `scripts/voice-processor.js`, lines 34-42 **Vulnerability Type**: OS command injection **Risk Level**: High **Vulnerable code:** ```javascript async function transcribeVoiceNote(audioFilePath) { try { const scriptDir = path.dirname(__filename); const transcribeScript = path.join(scriptDir, 'transcribe.py'); const { stdout, stderr } = require('child_process').execSync( `python "${transcribeScript}" "${audioFilePath}"`, { maxBuffer: 10 * 1024 * 1024, encoding: 'utf8' } ); ``` ### Technical Analysis `audioFilePath` is interpolated directly into a command string passed to `execSync`. By default, `execSync` processes a string through a system shell. Quoting the path does not make it safe because a path containing a double quote followed by shell metacharacters can terminate the quoted argument and append another command. The vulnerable `transcribeVoiceNote` function is exported as part of the public module API and is documented as accepting a caller-provided file path. Therefore, any integration that passes an untrusted or insufficiently validated path to this function creates a command-execution primitive. The code also incorrectly destructures the return value of `execSync`: with `encoding: 'utf8'`, the method returns a string rather than an object containing `stdout` and `stderr`. This causes normal transcription to fail when `stdout.match` is subsequently called. It does not prevent the injected shell command from running, because command execution occurs before the return value is processed. ### Attack Path 1. An attacker reaches an integration that exposes `transcribeVoiceNote` or otherwise controls the supplied audio path. 2. The attacker submits a path containing a closing quote and shell syntax, such as a path conceptually structured as `" ; attacker-command ; "`. 3. The application embeds that value into the command string with ...[truncated 743 chars]
Remediation
## Remediation Suggestions Replace shell-based execution with `execFile` or `spawn` and pass arguments as an array with shell processing disabled: ```javascript const { execFile } = require('child_process'); const { promisify } = require('util'); const execFileAsync = promisify(execFile); async function transcribeVoiceNote(audioFilePath) { const scriptDir = path.dirname(__filename); const transcribeScript = path.join(scriptDir, 'transcribe.py'); const { stdout } = await execFileAsync( 'python3', [transcribeScript, audioFilePath], { shell: false, maxBuffer: 10 * 1024 * 1024, encoding: 'utf8' } ); // Parse stdout here. } ``` Additionally: - Resolve and validate the path before use. - Restrict accepted paths to an explicitly permitted directory where appropriate. - Reject unexpected file types and non-regular files. - Run the process under a dedicated, least-privileged account. - Add regression tests using paths containing quotes, spaces, command separators, and substitution syntax.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/voice-processor.js:192
Finding
Predictable Temporary File Creation Permits Symlink and File-Race Attacks## Vulnerability Details **File Location**: `scripts/voice-processor.js`, lines 192-196 **Vulnerability Type**: Insecure temporary file creation **Risk Level**: Medium **Vulnerable code:** ```javascript async function processVoiceNote(audioBuffer, sender = 'user') { try { // Save to temp file const timestamp = Date.now(); const tempPath = path.join(process.env.TEMP || '/tmp', `voice-${timestamp}.ogg`); fs.writeFileSync(tempPath, audioBuffer); console.log(`[VOICE] Saved temp file: ${tempPath}`); ``` ### Technical Analysis The temporary filename is derived solely from `Date.now()` and is created directly in a shared temporary directory. Its value is predictable to nearby processes. `fs.writeFileSync` is used without exclusive-creation flags, without first creating a private temporary directory, and without explicitly applying restrictive permissions. On systems where another local user or compromised process can write to the temporary directory, that process can pre-create a predicted filename or a symbolic link at that path. The subsequent write can then follow the symbolic link or overwrite an existing file accessible to the skill's operating-system account. Voice messages can contain private communications, so permissive temporary-file access can also expose sensitive audio to other local users depending on the process umask and platform defaults. ### Attack Path 1. A local attacker observes or estimates when a voice message will be processed. 2. The attacker predicts the millisecond-based filename under `/tmp`, potentially creating several candidate names around the expected timestamp. 3. The attacker creates a symbolic link from a candidate path to a target file writable by the skill account. 4. `processVoiceNote` calls `fs.writeFileSync` on the predictable path. 5. The operating system follows the link, and the audio data overwrites or corrupts the target. 6. Alternatively, the atta ...[truncated 598 chars]
Remediation
## Remediation Suggestions Create a private temporary directory and a file with exclusive creation and restrictive permissions: ```javascript const os = require('os'); const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'voice-')); const tempPath = path.join(tempDir, 'audio.ogg'); const fd = fs.openSync( tempPath, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL, 0o600 ); try { fs.writeFileSync(fd, audioBuffer); } finally { fs.closeSync(fd); } ``` Also: - Do not rely on timestamps as security-sensitive identifiers. - Reject symbolic links and verify that the resulting path is a regular file. - Use the operating system's standard temporary-directory API. - Run the skill under a dedicated account with a restrictive umask. - Remove both the temporary file and its private directory in a `finally` block.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/voice-processor.js:225
Finding
Sensitive Voice Files Remain on Disk After Processing Errors## Vulnerability Details **File Location**: `scripts/voice-processor.js`, lines 225-240 **Vulnerability Type**: Sensitive temporary-data retention **Risk Level**: Medium **Vulnerable code:** ```javascript console.log('[RESULT]', finalResult); // Cleanup try { fs.unlinkSync(tempPath); } catch (e) {} return finalResult; } catch (e) { console.error('[ERROR]', e.message); return { status: 'error', error: e.message, response: 'Failed to process voice note' }; } } ``` The audio file is created earlier in the same function: ```javascript const timestamp = Date.now(); const tempPath = path.join(process.env.TEMP || '/tmp', `voice-${timestamp}.ogg`); fs.writeFileSync(tempPath, audioBuffer); ``` ### Technical Analysis Cleanup occurs only after all transcription, parsing, handler execution, and result construction steps complete successfully. If any operation throws after the temporary audio file has been written, control transfers directly to the `catch` block and the file is never removed. Failures can be induced by malformed or unsupported audio, unavailable Python dependencies, Whisper errors, resource exhaustion, or handler exceptions. Because the filename is predictable and stored in a shared temporary location, retained files may be discoverable by local users or processes. Repeated failures also accumulate files indefinitely. ### Attack Path 1. An attacker or ordinary user submits malformed, unsupported, or resource-intensive audio. 2. The application writes the complete audio buffer to the temporary directory. 3. Transcription or a later processing stage throws an exception. 4. Execution jumps to the `catch` block, bypassing `fs.unlinkSync`. 5. The sensitive audio file remains on disk. 6. A local attacker with applicable file access reads the retained message, or repeated failures consume available disk space. ### I ...[truncated 363 chars]
Remediation
## Remediation Suggestions Move cleanup into a `finally` block so it executes on both success and failure: ```javascript async function processVoiceNote(audioBuffer, sender = 'user') { let tempPath; try { // Securely create and process the temporary file. return finalResult; } catch (error) { return { status: 'error', error: error.message, response: 'Failed to process voice note' }; } finally { if (tempPath) { try { fs.unlinkSync(tempPath); } catch (cleanupError) { console.error('[VOICE] Temporary-file cleanup failed'); } } } } ``` Combine this change with private temporary directories and mode `0600`. Apply storage quotas and monitoring for abandoned files, and deploy a narrowly scoped cleanup process for files left by abrupt process termination. Avoid suppressing cleanup failures completely; log a sanitized operational event without exposing the audio path unnecessarily.

T08 · Insecure Dependencies

Warning
Location
references/SETUP.md:8
Finding
Ambiguous and Unpinned Python Dependencies Create Supply-Chain Risk## Vulnerability Details **File Location**: `references/SETUP.md`, lines 8-16; `requirements.txt`, lines 1-3 **Vulnerability Type**: Dependency confusion and insufficient dependency pinning **Risk Level**: Medium **Vulnerable setup instructions:** ```markdown ### Required Python Packages ```bash pip install whisper soundfile numpy ``` Or install all at once: ```bash pip install openai-whisper soundfile numpy ``` ``` **Unpinned dependency manifest:** ```text openai-whisper>=20231117 soundfile>=0.12.1 numpy>=1.21.0 ``` ### Technical Analysis The setup guide offers `pip install whisper` even though the intended dependency declared by the project is `openai-whisper`. Those are distinct package-index names. Users following the first command may install an unintended package that exposes the same or a misleading import name. In addition, every requirement uses only a lower bound. Future package versions are accepted automatically, and no integrity hashes are supplied. Consequently, installation results can change over time without any modification to the audited project. A compromised upstream release, dependency takeover, or incompatible future release could therefore enter the environment during installation. This finding concerns unsafe dependency resolution. The audited repository itself does not contain evidence that the named packages are presently malicious. ### Attack Path 1. An administrator follows the documented `pip install whisper soundfile numpy` command. 2. The Python package index resolves `whisper`, which is not necessarily the intended `openai-whisper` distribution. 3. Package installation executes any build or installation hooks supplied by the resolved distribution. 4. The application later imports `whisper`, potentially loading unintended code. 5. Separately, the lower-bound-only requirements allow a future compromised release to be selected automatically during a later deploymen ...[truncated 486 chars]
Remediation
## Remediation Suggestions - Remove every instruction that installs the ambiguous `whisper` package. - Refer exclusively to the intended distribution name, `openai-whisper`. - Install dependencies from one canonical root-level manifest rather than duplicating package commands throughout documentation. - Pin reviewed versions exactly rather than using unrestricted lower bounds. - Generate and verify hashes through a lock file or a tool such as `pip-compile --generate-hashes`. - Review transitive dependencies and update them through a controlled process. - Use a trusted internal package mirror where appropriate. - Install inside an isolated virtual environment under a non-privileged account. A hardened manifest should use exact reviewed versions and hashes, conceptually: ```text openai-whisper==REVIEWED_VERSION --hash=sha256:REVIEWED_HASH soundfile==REVIEWED_VERSION --hash=sha256:REVIEWED_HASH numpy==REVIEWED_VERSION --hash=sha256:REVIEWED_HASH ``` The actual versions and hashes must be generated from artifacts reviewed and tested by the project maintainers.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/voice-processor.js:219
Finding
Full Voice Transcripts and Sender Metadata Are Exposed Through Logs## Vulnerability Details **File Location**: `scripts/voice-processor.js`, lines 219-225; additional exposure in `scripts/voice-listener-daemon.js`, lines 46-54 **Vulnerability Type**: Sensitive information exposure through logging **Risk Level**: Low **Vulnerable processor code:** ```javascript const finalResult = { status: result.status, response: result.response, transcript: transcript, intent: parsed.intent, language: language, sender: sender, timestamp: timestamp }; console.log('[RESULT]', finalResult); ``` **Vulnerable listener code:** ```javascript if (result.status === 'success') { console.log(`[LISTENER] ✅ Processed: "${result.transcript}"`); console.log(`[LISTENER] Response: "${result.response}"`); // Emit response event for parent process to handle sending console.log(JSON.stringify({ type: 'voice-response', data: result })); ``` ### Technical Analysis The application writes complete transcribed conversations, generated responses, and the full result object to standard output. The result object can include sender identifiers. The daemon repeats the transcript and response and then serializes the complete result again. In production, standard output is commonly retained by process managers, container platforms, system journals, or centralized logging systems. This creates additional persistent copies of private communication content outside the application's primary data flow. The logging is unconditional and has no debug flag, redaction policy, or minimization control. ### Attack Path 1. A user sends a voice message containing private or sensitive information. 2. Whisper converts the message into text. 3. The processor writes the complete transcript and result object to standard output. 4. The listener writes the transcript, response, and serialized result again. 5. A process manager or centralized logging agent stores these messages. ...[truncated 598 chars]
Remediation
## Remediation Suggestions Disable transcript and sender logging by default. Log only minimal operational metadata, such as a generated request ID, success status, processing duration, and a coarse error code: ```javascript console.log('[VOICE]', { requestId, status: finalResult.status, intent: finalResult.intent, language: finalResult.language }); ``` Additionally: - Place content-level logging behind an explicit development-only flag. - Redact or pseudonymize sender identifiers. - Do not serialize the complete result object to logs as an event transport mechanism; use an authenticated inter-process channel with a defined schema. - Apply least-privilege access controls to logs. - Configure short retention periods and encryption for any logs that may contain personal data. - Document the logging and privacy policy for operators.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (31)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill claims streaming TTS responses and broader customizable command handling, while the visible design suggests simple local file processing and text-only return values. In a voice and automation context, overstated capabilities can mask missing controls and mislead users into enabling command execution paths or message-handling workflows that were never properly secured.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill claims streaming TTS responses and broader customizable command handling, while the visible design suggests simple local file processing and text-only return values. In a voice and automation context, overstated capabilities can mask missing controls and mislead users into enabling command execution paths or message-handling workflows that were never properly secured.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The skill claims streaming TTS responses and broader customizable command handling, while the visible design suggests simple local file processing and text-only return values. In a voice and automation context, overstated capabilities can mask missing controls and mislead users into enabling command execution paths or message-handling workflows that were never properly secured.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation promotes automatic listening, transcription, and processing of WhatsApp voice messages but does not disclose privacy, consent, retention, or third-party processing risks. In this skill context, users may deploy it against real personal communications, so missing warnings can lead to unauthorized collection or transmission of sensitive message content to Whisper/OpenAI-related tooling or local logs.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill documentation encourages voice-driven IoT, smart home, device, and drone operations without warning about authentication, confirmation, spoofing, or mis-transcription risks. Because this is a WhatsApp voice interface using automated intent execution, ambiguous or malicious audio could trigger state-changing actions in the physical world, making the omission materially dangerous in this context.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises functionality that inherently touches local files, likely networked services, and possibly environment-derived configuration, but it declares no explicit tool scope or permissions. In an agent ecosystem, that omission weakens security boundaries and user awareness, making it easier for the skill to access sensitive resources without clear approval or review.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documentation lacks an upfront privacy notice that voice content may be transcribed and passed through multiple processing components, potentially including external services and messaging flows. Voice data often contains sensitive personal information, so failing to disclose these data flows increases the risk of improper collection, transfer, or retention.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill instructs users to run a daemon that continuously watches a local inbound directory for voice files, but it does not prominently warn that monitoring is persistent and automatic. That creates a privacy and consent risk because users or admins may not realize private voice messages are being continuously ingested and processed.

Context-Inappropriate Capability

Medium
Confidence
87% confidence
Finding
The manifest describes a WhatsApp voice interface that transcribes voice notes, detects intent, and executes handlers, with examples like weather, status, and commands. This example file encourages integrating handlers that control smart-home devices, query a drone SDK, and control a music player, which are external operational capabilities not justified by the stated skill purpose itself.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The smart-home handler immediately toggles a real device state after intent match, with no confirmation, authorization check, or validation of user identity. In a WhatsApp voice interface, mis-transcription, spoofed audio, or unauthorized message sources could cause unintended physical-world actions such as turning devices on or off.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The file states that language detection returns only 'en' or 'hi', and later handler examples default responses to English/Hindi only. This is a natural-language policy concern because it imposes a locale/language constraint without documenting user opt-in or a clear region-specific justification.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The documentation describes automatic processing of inbound voice messages and storage of a processed-files log, but does not mention consent, retention, access controls, or privacy implications of transcribing user audio. In a WhatsApp voice-processing skill, this can lead integrators to deploy collection and storage of sensitive user speech data without adequate privacy safeguards, increasing risk of unauthorized retention or disclosure.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The setup guide recommends running a background daemon that automatically watches and processes incoming WhatsApp voice messages, but it provides no notice about consent, retention, or handling of sensitive audio/transcripts. In a voice-messaging context, this can lead to non-consensual processing of personal data and privacy violations, especially because the system continuously monitors inbound media and converts speech to text.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The documentation states transcription defaults to English and only suggests manual override, without addressing user choice or the risk of mis-transcription for non-English speakers. While not a direct code-execution issue, this can cause inaccurate processing of user content and unintended disclosure or mishandling of sensitive voice data when users expect language-aware treatment.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The manifest describes a WhatsApp voice processing skill that supports English and Hindi with automatic language detection. This script hard-codes `language="en"` in the Whisper transcription call, which prevents automatic detection and does not align with Hindi support as described.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The code hard-codes `language="en"` for transcription, which enforces a specific language/locale regardless of the input or user preference. This is a natural-language policy concern because it removes user choice and may produce incorrect or exclusionary behavior for non-English audio.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This daemon logs the full transcribed voice content and generated response text to stdout, which can expose sensitive personal, operational, or authentication-related information contained in WhatsApp voice notes. In a real-time messaging skill, logs are often centralized, retained, or accessible to operators, so storing raw transcripts increases privacy and data leakage risk beyond the original chat context.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The header comment says the processor 'Responds via TTS', implying speech output generation. In practice, the handlers and main flow only build string responses and return them in JSON-like objects, with no TTS invocation or audio output anywhere in the file.

Context-Inappropriate Capability

Medium
Confidence
77% confidence
Finding
While transcription itself matches the manifest, spawning a separate interpreter via shell command is a broader execution capability than the manifest describes. The stated purpose is voice-note processing, not general local code execution, so this implementation adds an unjustified capability surface.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The code logs full transcribed speech with console.log, which can expose sensitive user content in application logs. In a WhatsApp voice-processing context, transcripts may contain personal, financial, health, or authentication information, making log access a meaningful confidentiality risk.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The language-selection logic deterministically chooses only 'en' or 'hi' from character counts, and later responses are generated in that chosen language. This is a natural-language policy issue because it imposes a language/locale decision without an explicit user choice, opt-in, or documented justification.

Missing User Warnings

Medium
Confidence
81% confidence
Finding
The weather handler performs an HTTP request to an external endpoint, and the skill overall processes user voice content and system data without any explicit user warning about external network activity. For code-file review, network transmission that could involve user or system data should have some visible disclosure unless already clearly documented as expected behavior.

Ssd 3

Medium
Confidence
95% confidence
Finding
The code echoes transcribed speech back in error responses and includes the transcript in returned and logged result objects. This creates a natural-language data leakage path where sensitive spoken content may be exposed to downstream systems, logs, support tooling, or unintended recipients.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The manifest describes end-to-end voice handling including 'streaming responses via TTS', but the implemented processing pipeline stops at producing a text response object. No text-to-speech synthesis, audio generation, or streaming behavior appears in this module despite the top-level documentation presenting it as the voice processor.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill writes raw voice-note audio to a predictable temporary file on disk before transcription. Temporary storage of sensitive audio increases exposure if the host is shared, if temp directories are accessible to other users/processes, or if cleanup fails after crashes.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/voice-processor.js:39

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/voice-processor.js:195