Back to skill

Security audit

VoScript API

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it claims, but it handles sensitive audio, transcripts, API keys, and voiceprints while allowing insecure HTTP and command-line secrets.

Review this before installing if you will use real recordings or identifiable speakers. Prefer HTTPS for any non-local VoScript server, avoid passing API keys on the command line, confirm you have consent to upload speech or enroll voiceprints, and be careful with rename/delete actions because they change persistent server data.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/common.py:403
Finding
Sensitive API credentials, audio, transcripts, and biometric data may be transmitted over plaintext HTTP## Vulnerability Details **File Location**: `scripts/common.py:403-419`; insecure HTTP use is documented in `SKILL.md:71-81, 104-106` and `references/configuration.md:20-21, 82-83` **Vulnerability Type**: Plaintext transmission of sensitive information **Risk Level**: High ### Vulnerable Code ```python resolved_url = url or os.environ.get("VOSCRIPT_URL") resolved_key = api_key or os.environ.get("VOSCRIPT_API_KEY") if not resolved_url: raise ValueError(t("url_empty")) if not resolved_key: raise ValueError(t("key_empty")) self.url = resolved_url.rstrip("/") self.api_key = resolved_key self.timeout = timeout self._session = requests.Session() self._session.headers.update( { "X-API-Key": self.api_key, "Accept": "application/json", } ) ``` The documentation explicitly permits plaintext HTTP: ```text - VOSCRIPT_URL: Service address, for example http://localhost:7880 - Local deployment: http://localhost:7880 - LAN deployment: http://<nas-ip>:7880 or a custom domain ``` It also recommends HTTP as a fallback for certificate problems: ```text For self-signed certificate issues, contact the deployment administrator for a trusted certificate or use HTTP instead. ``` The documented upload sends both the credential and audio over the configured transport: ```bash curl -X POST "$VOSCRIPT_URL/api/transcribe" \ -H "X-API-Key: $VOSCRIPT_API_KEY" \ -F "file=@/path/to/audio.wav" ``` ### Technical Analysis `VoScriptClient` accepts either HTTP or HTTPS and unconditionally attaches the static API key to its session. It does not reject or require explicit confirmation for plaintext HTTP on non-loopback hosts. This behavior is especially sensitive because the client handles: - Static API credentials. - User-selected audio recordings. - Full transcript text and original filenames. - Speaker names and mappings. - Persistent biometric voicepr ...[truncated 2123 chars]
Remediation
## Remediation Suggestions 1. Require HTTPS whenever the destination is not a loopback address. 2. Permit plaintext HTTP only for `localhost`, `127.0.0.1`, and `::1`, or behind an explicit high-friction option such as `--allow-insecure-http`. 3. Validate the parsed URL during client initialization and reject unsupported schemes, missing hostnames, embedded credentials, and non-loopback HTTP destinations. 4. Remove the documentation recommendation to use HTTP when certificates fail. 5. Support a configurable trusted CA bundle for private or self-signed deployments, while retaining certificate verification. 6. Document secure reverse-proxy deployment with TLS and appropriate network access controls. 7. Prefer short-lived, endpoint-scoped credentials over a static key with broad read, write, and delete capabilities. 8. Rotate any API key that may already have been used over an untrusted plaintext connection.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/common.py:564
Finding
API keys supplied through command-line arguments may leak through process listings and shell history## Vulnerability Details **File Location**: `scripts/common.py:564-579`; command-line secret use is documented in `SKILL.md:74-81` and `references/configuration.md:57-63` **Vulnerability Type**: Insecure credential handling **Risk Level**: Medium ### Vulnerable Code ```python def add_common_args(parser: "object") -> None: """Attach ``--url`` and ``--api-key`` to an ``argparse.ArgumentParser``. Typed as ``object`` to avoid importing argparse at module import time (scripts import argparse themselves). """ parser.add_argument( "--url", default=None, help="VoScript server base URL (falls back to $VOSCRIPT_URL).", ) parser.add_argument( "--api-key", default=None, help="VoScript API key (falls back to $VOSCRIPT_API_KEY).", ) ``` The documentation presents direct command-line use as a standard configuration method: ```bash python ${SKILL_PATH}/scripts/list_transcriptions.py \ --url http://nas.example.com:7880 \ --api-key your_api_key_here ``` ### Technical Analysis Secrets passed as command-line arguments may be exposed through: - Shell history files. - Process-listing interfaces and system monitoring tools. - CI/CD command logs. - Terminal session recording. - Diagnostic and crash-report collection. - Automation wrappers that log complete command invocations. The environment-variable fallback reduces the need for this interface, but the Skill explicitly documents `--api-key` as an ordinary override without warning users about its exposure characteristics. Because the key can authorize access to transcripts and persistent voiceprint operations, disclosure is security-relevant. This issue does not represent hidden credential theft by the Skill. It is an insecure secret-input mechanism that may disclose the key to other local principals or logging systems. ### Attack Path 1. A user follows the doc ...[truncated 1057 chars]
Remediation
## Remediation Suggestions 1. Remove or deprecate the `--api-key` command-line option. 2. Prefer a protected environment variable, operating-system keychain, secret manager, or permission-restricted configuration file. 3. Add an interactive secret prompt using `getpass.getpass()` when no secure configuration source is available. 4. If command-line compatibility must be retained, display a clear warning that the value may enter shell history and process listings. 5. Remove examples that place a real key directly in a command invocation. 6. Ensure CI/CD documentation uses masked secret variables and does not echo expanded commands. 7. Recommend restrictive permissions for configuration files and process environments. 8. Rotate credentials after suspected command-line, history, or log exposure.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
|------|------|------|
| 查看详情 | `GET /api/voiceprints/{speaker_id}` | — |
| 重命名 | `PUT /api/voiceprints/{speaker_id}/name` | 表单字段 `name` |
| 删除 | `DELETE /api/voiceprints/{speaker_id}` | — |

```bash
curl -X GET "$VOSCRIPT_URL/api/voiceprints/<SPEAKER_ID>" \
Confidence
80% 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).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- get:    GET    /api/voiceprints/{speaker_id}
- rename: PUT    /api/voiceprints/{speaker_id}/name   form: name
- delete: DELETE /api/voiceprints/{speaker_id}

``delete`` is irreversible. When running in an interactive terminal the
script prompts for explicit ``yes`` confirmation; use ``--yes`` to skip.
Confidence
90% 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).

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill clearly instructs an agent to use environment variables, shell commands, network access, and file output, but it does not declare any explicit tool scope or permission boundaries. In an agent ecosystem, that omission increases the chance that a host agent will grant broader-than-necessary capabilities, enabling unintended command execution, network access, or writing sensitive transcript data to disk without clear policy constraints.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This skill handles audio uploads and voiceprint enrollment, which involve transmitting potentially sensitive speech content and processing biometric identifiers, yet it does not prominently warn about privacy, consent, retention, or secure transport. In practice, an agent could upload confidential conversations or create biometric profiles without the user appreciating the sensitivity or obtaining consent from recorded speakers.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The documentation exposes voiceprint deletion and related management actions without clearly warning that deletion may be irreversible and may remove biometric enrollment data needed for future identification. In an agent setting, a user or autonomous workflow could trigger deletion casually, causing permanent loss of biometric records and degrading recognition quality or auditability.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
This markdown file contains user-facing operational guidance only in Chinese, and there is no indication that users can choose another language or that the skill is intentionally limited to a Chinese-speaking context. Under the natural-language policy rule, forcing a specific language without opt-in is a policy concern.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
This markdown file uses Chinese throughout, including headings, instructions, and operational guidance, but does not indicate that the language is optional or limited to a specific Chinese-speaking deployment context. Under the policy rule for natural-language violations, forcing a specific language without user opt-in is a reportable issue.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The `_columns()` function selects Chinese labels only when `LANG == "zh"`, otherwise defaulting to English. This creates a language/locale constraint in behavior without any visible user opt-in or choice mechanism in this file, which matches the policy concern for forced language selection.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The file hard-codes two language modes and selects them implicitly via a global LANG value, rather than exposing a user opt-in or documenting a justified locale restriction. This can violate language/locale policy expectations because the behavior is controlled internally instead of by an explicit user choice in this script.

Static analysis

No suspicious patterns detected.