T09 · Insecure Skill Coding Practices
- Location
scripts/transcribe.py:228- Finding
API Credential Exposure Through Command-Line Arguments
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This appears to be a real speech-to-text skill, but it needs review because it can record and upload sensitive audio and its install/API guidance lacks important safeguards.
Review before installing. Prefer a virtual environment instead of --break-system-packages, pin or lock dependencies, avoid passing API keys on the command line, use only HTTPS API endpoints unless intentionally using localhost, and treat recordings/transcripts as sensitive files that remain on disk until deleted.
scripts/transcribe.py:228API Credential Exposure Through Command-Line Arguments
scripts/transcribe.py:181Sensitive Audio and Credentials Can Be Sent Over Plaintext HTTP
requirements.txt:6Unpinned Dependencies Installed With System Package Protections Disabled
Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.
代码块的核心功能是“录音并保存 WAV 文件”,这可以作为 STT 流程的前置步骤,但本身不是语音转文字工具的完整实现。声明中强调支持本地 Whisper 和云端 API 转写,而代码中没有导入或调用 faster-whisper、OpenAI 兼容接口、HTTP 请求库,也没有任何音频到文本的处理逻辑。因此,描述显著高于代码实际能力,属于用途与行为不一致。录音和设备列表属于声明中提到的支持性部分,但不足以支撑‘语音转文字’这一主要功能声明。
The skill documents shell commands, environment-variable use, file creation, and persistent storage behavior, but it does not declare any explicit tool scope such as permissions or allowed-tools. This weakens user and platform visibility into what the skill may access or modify, increasing the chance of over-broad execution and accidental misuse.
The skill captures microphone audio and stores recordings and transcriptions persistently, but the description lacks a clear upfront privacy warning. Users may invoke it without realizing sensitive speech will be recorded and retained on disk, which can expose credentials, private conversations, or regulated data.
The API transcription mode sends audio to a remote service, but the documentation does not explicitly warn that user speech may leave the local machine. In a speech-processing skill, this materially changes the privacy and trust model and can expose sensitive spoken data to third parties.
This example documents use of a remote API endpoint for transcription, which entails external transmission of user audio and potentially derived text. In the context of an STT skill, external transmission is expected functionality, but it is still security-relevant because spoken content may be sensitive.
python3 scripts/transcribe.py audio.wav
--engine api
--api-url https://api.openai.com/v1
--api-key sk-xxx
--model whisper-1
The environment-variable example configures a remote transcription service, again enabling external transfer of user audio and possibly transcripts. Although consistent with the declared cloud mode, it is dangerous without clear consent and privacy disclosure because the skill handles microphone-derived data.
API 模式设置示例:
export STT_API_URL=https://api.openai.com/v1
export STT_API_KEY=sk-your-key
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# Ubuntu/Debian
sudo apt-get install portaudio19-dev libasound-dev
# macOS
brew install portaudio
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# Ubuntu/Debian
sudo apt-get install portaudio19-dev libasound-dev
# macOS
brew install portaudio
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
]
# Use subprocess.run with shell=False to prevent shell injection via output_path
try:
subprocess.run(cmd, check=True, capture_output=True)
print(f" Saved: {output_path}")
except subprocess.CalledProcessError as e:
print(f"ERROR: arecord failed with code {e.returncode}", file=sys.stderr)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print(sd.query_devices())
else:
# Try using arecord -l
result = subprocess.run(['arecord', '-l'], capture_output=True, text=True)
if result.returncode != 0:
print('No arecord available')
else:
When the API engine is used, the script uploads the full audio file to a remote OpenAI-compatible endpoint, but the code provides only generic logging and no explicit privacy warning or confirmation that data will leave the local machine. In an STT skill, audio may contain highly sensitive speech, so silent transmission to arbitrary configured endpoints creates a meaningful confidentiality risk.
The manifest describes the skill as a speech-to-text recognizer/transcription tool, but the CLI explicitly exposes a 'translate' task and the transcription backends implement translation behavior. Translation changes the semantic function from transcription to cross-language transformation, which is broader than plain STT.
The --task help text states that translate means translation 'to English', which imposes a specific output language choice in the skill's natural-language interface. This is a locale/language policy issue because the user is not offered a language choice or explicit opt-in beyond selecting a generic translation task.
The natural-language display name includes both English and Chinese variants separated by a pipe, which imposes a specific locale presentation choice in metadata without any indication of user preference, opt-in, or region-specific justification. This may violate language/locale policy where skills must not force a particular language presentation absent user choice.
The dependency is specified with a minimum version only, so installs are not reproducible and may pull in newer releases with undiscovered or incompatible behavior. In a speech-to-text skill, this increases supply-chain and stability risk, though the file itself does not indicate an actively malicious package choice.
# ── Core STT Engines ────────────────────────────────────────────────────────
# Option 1: faster-whisper (recommended - GPU/CPU efficient)
faster-whisper>=1.0.0
# Option 2: openai-whisper (full model, slower but accurate)
# Note: Install ONLY one of faster-whisper or whisper, not both
Using an unpinned PyAudio version allows different environments to install different releases, which can introduce vulnerable or breaking versions without notice. This is a low-severity supply-chain hygiene issue rather than a direct exploitable flaw in the requirements file itself.
# ── Audio Recording ─────────────────────────────────────────────────────────
# Option 1: PyAudio (cross-platform)
pyaudio>=0.2.14
# Option 2: SoundDevice + SoundFile (alternative)
# sounddevice>=0.4.5
The OpenAI client library is unpinned, which means dependency resolution may select any newer version above the minimum. For a skill that can send audio to a cloud API, uncontrolled upgrades raise supply-chain and operational risk, even if no immediate exploit is visible here.
# ── API Support ────────────────────────────────────────────────────────────
# For OpenAI-compatible API transcription
openai>=1.0.0
# ── Core ───────────────────────────────────────────────────────────────────
numpy>=1.24.0
NumPy is unpinned, so builds are non-reproducible and may resolve to versions with known defects or future regressions. Because this is a foundational package with a history of advisories, leaving it unconstrained increases uncertainty about deployed risk.
openai>=1.0.0
# ── Core ───────────────────────────────────────────────────────────────────
numpy>=1.24.0
torch>=2.0.0
# ── Platform-specific ──────────────────────────────────────────────────────
The finding is valid because numpy has known advisories and the manifest does not pin a version, making it impossible to verify whether an installed version is affected. In this STT context the requirements file alone does not prove exploitability, but it does leave a real unresolved dependency-risk gap.
Torch is unpinned, creating non-deterministic installs for a large, security-relevant package with prior high-impact advisories. In ML tooling, unreviewed upgrades can materially expand attack surface or expose vulnerable code paths, making this somewhat more concerning than ordinary library drift.
# ── Core ───────────────────────────────────────────────────────────────────
numpy>=1.24.0
torch>=2.0.0
# ── Platform-specific ──────────────────────────────────────────────────────
# Linux: for ALSA audio recording
This is a real issue because torch has multiple known advisories and the unpinned requirement prevents verification that deployed installations are safe. Given PyTorch's history of serious issues, including code-execution-related cases, the lack of version control is more dangerous in an ML-focused skill than in a minimal utility package.
The script accepts STT_API_KEY from the environment and --api-key from the command line, but provides no warning or documentation about handling sensitive credentials. For safety-sensitive operations involving secrets, the file should disclose that credentials are being consumed and recommend safer usage patterns.
No suspicious patterns detected.