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

Content
View full analysis

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
View 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.

Content

No source excerpt is available for this finding.

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

High
Category
Data Flow
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.

Content

Scanner excerpt · scripts/transcribe.py (reported line 174)May include surrounding context.

python
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}")

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
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.

Content

Scanner excerpt · api-reference.md (reported line 6)May include surrounding context.

Endpoint

text
POST https://api.senseaudio.cn/v1/audio/transcriptions
Content-Type: multipart/form-data
Authorization: Bearer $API_KEY

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/transcribe.py (reported line 43)May include surrounding context.

python
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] = {}

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/transcribe.py (reported line 101)May include surrounding context.

python
if not ffprobe:
        return None
    try:
        result = subprocess.run(
            [ffprobe, "-v", "quiet", "-print_format", "json", "-show_format", filepath],
            capture_output=True, text=True
        )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/transcribe.py (reported line 133)May include surrounding context.

python
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

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.