Back to skill

Security audit

audio-transcribe-summarize

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent, but it deserves review because it uploads recordings to SenseAudio and also saves and prints transcript data more broadly than its instructions disclose.

Install only if you are comfortable sending selected recordings to SenseAudio and storing transcript artifacts locally. Avoid confidential, regulated, or third-party recordings unless you have permission and understand the service's data handling; check for the .txt and .json outputs and avoid running it where stdout is centrally logged.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/transcribe.py:284
Finding
Sensitive Transcript Data Exposed Through Undisclosed JSON Output and Console Preview## Vulnerability Details **File Location**: `scripts/transcribe.py:284-291` **Vulnerability Type**: Sensitive data exposure through excessive local output and logging **Risk Level**: Medium ### Vulnerable Code ```python json_path = str(Path(output_path).with_suffix(".json")) with open(json_path, "w", encoding="utf-8") as f: json.dump(raw_results if len(raw_results) > 1 else raw_results[0], f, ensure_ascii=False, indent=2) duration_info = "" if raw_results and isinstance(raw_results[0], dict): dur = raw_results[0].get("duration") or (raw_results[0].get("audio_info") or {}).get("duration") ``` The associated console exposure occurs immediately afterward: ```python print(f"\nDone! Transcript saved to: {output_path}{duration_info}") print(f"Raw JSON saved to: {json_path}") print(f"\nPreview (first 500 chars):\n{full_transcript[:500]}") ``` ### Technical Analysis The script creates a raw JSON sidecar in addition to the documented transcript text file. This JSON can contain the complete transcript and sensitive derived information, including speaker identities or labels, timestamps, sentiment results, translations, and audio metadata. The Skill documentation describes the transcript text output but does not clearly disclose this additional raw JSON artifact. The script also prints the first 500 characters of the transcript to standard output without requiring explicit user consent. Standard output is frequently retained by terminal capture systems, AI-agent execution logs, CI/CD systems, centralized telemetry, support diagnostics, or process supervisors. Both files are created using the process's default permission behavior. No explicit owner-only permissions are applied, so the effective accessibility depends on the user's `umask`, output directory permissions, and platform defaults. This exceeds the minimum data exposure required to provide a transcript: neither persistent raw API output nor a transcript p ...[truncated 1792 chars]
Remediation
## Remediation Suggestions 1. Make raw JSON persistence opt-in through an explicit option such as `--raw-json-output FILE`; do not create it during normal transcription. 2. Remove the transcript preview from default console output. If previews are retained, require an explicit `--preview` option and warn that transcript content will be emitted to logs. 3. Clearly document every generated file, the information it contains, and its privacy implications. 4. Create transcript and JSON files with owner-only permissions where supported, such as mode `0600`, and avoid inheriting insecure default permissions. 5. Warn before overwriting existing output files and consider atomic file creation with exclusive creation semantics. 6. Provide a privacy mode that suppresses transcript content from stdout and avoids retaining raw API responses. 7. Recommend that users select a protected output directory and delete transcript artifacts when they are no longer required. 8. Close uploaded file handles deterministically by using a context manager around the file opened for the multipart request.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared behavior says the skill transcribes and summarizes, but the documented implementation only runs a transcription script and writes outputs locally, while summary generation is left to a later manual step. This mismatch is security-relevant because hidden or undeclared side effects—especially local file writes—reduce transparency and can cause users to approve actions they did not expect.

Tainted flow: 'files' from open (line 148, file read) → requests.post (network output)

High
Category
Data Flow
Content
else:
            data["timestamp_granularities[]"] = args.timestamps

    response = requests.post(API_URL, headers=headers, files=files, data=data, timeout=300)

    if response.status_code != 200:
        print(f"API Error ({response.status_code}): {response.text}")
Confidence
98% confidence
Finding
The script reads arbitrary local audio/video content and transmits it to a third-party transcription service over the network. In the context of a transcription skill, this is expected functionality, but it is still a real privacy and data-handling risk because recordings may contain sensitive personal, corporate, legal, or regulated information and the transfer happens without any consent gate or policy enforcement in code.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill invokes sensitive capabilities—environment access, filesystem writes, network access, and shell execution—without declaring any explicit tool scope or permissions boundary. This makes the operational surface larger than what a reviewer or user can infer from metadata, increasing the risk of unintended data access, exfiltration, or unsafe command execution.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The invocation text is broad enough to match many ordinary requests involving recordings, notes, lectures, interviews, or podcasts, which can cause the skill to trigger in situations where the user did not intend third-party transcription. In this context, over-broad matching is more dangerous because the skill sends potentially sensitive audio to an external API.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill does not clearly warn users that uploaded audio/video content will be transmitted to an external service at api.senseaudio.cn. Because recordings may contain personal, confidential, or regulated information, lack of disclosure undermines informed consent and can lead to privacy, compliance, and data-handling violations.

External Transmission

Medium
Category
Data Exfiltration
Content
## Endpoint

```
POST https://api.senseaudio.cn/v1/audio/transcriptions
Content-Type: multipart/form-data
Authorization: Bearer $API_KEY
```
Confidence
79% confidence
Finding
This reference defines an external network destination for transcription, meaning user-provided audio leaves the local environment and is transmitted to a remote service. In the context of a transcription skill, that behavior is expected, but it is still security-relevant because recordings can contain sensitive content and the endpoint is outside the user's trust boundary.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill documentation instructs sending user audio to a third-party external API with a bearer token but provides no privacy, consent, retention, or cross-border transmission warning. Because audio may contain sensitive personal, meeting, or confidential business information, omission of disclosure and consent requirements creates a real privacy and data-handling risk in normal use.

External Transmission

Medium
Category
Data Exfiltration
Content
print("Error: 'requests' package required. Install with: pip install requests")
    sys.exit(1)

API_URL = "https://api.senseaudio.cn/v1/audio/transcriptions"
MAX_FILE_SIZE = 10 * 1024 * 1024  # 10MB

_bin_cache: dict[str, str | None] = {}
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if not ffprobe:
        return None
    try:
        result = subprocess.run(
            [ffprobe, "-v", "quiet", "-print_format", "json", "-show_format", filepath],
            capture_output=True, text=True
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
for i in range(num_chunks):
        start = i * chunk_duration
        chunk_path = os.path.join(tmp_dir, f"chunk_{i:04d}{ext}")
        subprocess.run(
            [ffmpeg, "-y", "-i", filepath, "-ss", str(start), "-t", str(chunk_duration),
             "-acodec", "copy", "-vn", chunk_path],
            capture_output=True
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The code uploads user-provided audio to a remote API but does not present an explicit runtime warning or consent prompt about external transmission, privacy, or jurisdictional handling. Because this skill is specifically designed for transcribing recordings, the context makes this more important, not less, since users may assume local-only processing for meetings or interviews.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
The example explicitly presents "Transcribe and translate to English" using `--translate en`. This is a natural-language locale preference embedded in the skill guidance, and there is no accompanying note to confirm the user's preferred output language before translating.

Static analysis

No suspicious patterns detected.