Back to skill

Security audit

Audio Processing (Iyeque)

Security checks for vulnerabilities and agentic risk

Overview

The skill performs legitimate audio tasks, but its file-safety checks can be bypassed with symlinks and its Google TTS feature sends text to an external service without clear warning.

Review before installing. Do not send secrets, regulated data, or private transcripts to the TTS action unless you accept Google processing the text. Run it in a sandbox, avoid invoking it on untrusted workspace symlinks, and prefer pinned dependencies or a locked environment.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
tool.py:11
Finding
Workspace Isolation Bypass Through Symbolic Links## Vulnerability Details **File Location**: `tool.py`, lines 11–30; affected sinks include lines 61–65, 88–98, 105–109, 124–137, and 204–243 **Vulnerability Type**: Symbolic-link-based workspace containment bypass **Risk Level**: High ### Vulnerable Code ```python # SECURITY: Validate file paths to prevent path traversal def validate_file_path(file_path, must_exist=True): """Validate file path for security - must be within workspace""" if not file_path: return None # Resolve to absolute path abs_path = os.path.abspath(file_path) workspace_root = os.path.abspath(os.getcwd()) # SECURITY: Enforce workspace containment - file MUST be inside current working directory if not abs_path.startswith(workspace_root + os.sep) and abs_path != workspace_root: raise ValueError(f"Access denied: file must be within workspace ({workspace_root})") # SECURITY: Block sensitive system directories (defense in depth) forbidden_prefixes = ['/etc/', '/proc/', '/sys/', '/root/', '/home/'] for prefix in forbidden_prefixes: if abs_path.startswith(prefix): raise ValueError(f"Access denied: cannot access {prefix} directories") if must_exist and not os.path.exists(abs_path): raise FileNotFoundError(f"File not found: {abs_path}") return abs_path ``` Representative read sink: ```python def transcribe(file_path, model_name="base"): try: # SECURITY: Validate file path safe_path = validate_file_path(file_path, must_exist=True) whisper = get_whisper() model = whisper.load_model(model_name) result = model.transcribe(safe_path) return {"text": result["text"], "segments": result.get("segments", [])} ``` Representative write sink: ```python # SECURITY: Validate output path safe_output = validate_file_path(output_path, must_exist=Fals ...[truncated 2870 chars]
Remediation
## Remediation Suggestions 1. Resolve the real filesystem locations of both the workspace and candidate path before performing containment checks: ```python from pathlib import Path workspace_root = Path.cwd().resolve(strict=True) candidate = Path(file_path).resolve(strict=must_exist) try: candidate.relative_to(workspace_root) except ValueError: raise ValueError("Access denied: path is outside the workspace") ``` 2. Reject symbolic links when they are unnecessary. Check every existing path component, not only the final component, because a parent directory can also be a symlink. 3. For output files, reject existing symbolic links and create the destination atomically using operating-system no-follow and exclusive-creation controls where available, such as `O_NOFOLLOW` and `O_EXCL`. 4. Avoid a check-then-use race. Where possible, open a validated file descriptor securely and pass that descriptor to the consumer instead of validating a path and reopening it later. 5. Use `os.path.commonpath()` or `Path.relative_to()` rather than string-prefix comparisons for containment checks. 6. Add regression tests covering final-component symlinks, symlinked parent directories, broken output symlinks, relative traversal, and attempts to replace a validated file with a symlink between validation and use.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:9
Finding
Unpinned Third-Party Dependencies Create Supply-Chain Risk## Vulnerability Details **File Location**: `SKILL.md`, lines 9–27 and 54–66 **Vulnerability Type**: Unconstrained third-party package installation **Risk Level**: Medium ### Vulnerable Code ```yaml "requires": { "bins": ["ffmpeg", "python3"], "pip": ["openai-whisper", "gTTS", "librosa", "pydub", "soundfile", "numpy", "webrtcvad-wheels"] }, "install": [ { "id": "ffmpeg", "kind": "brew", "package": "ffmpeg", "label": "Install ffmpeg", }, { "id": "python-deps", "kind": "pip", "package": "openai-whisper gTTS librosa pydub soundfile numpy webrtcvad-wheels", "label": "Install Python dependencies", } ], ``` The documented execution commands also request dependencies without exact versions: ```bash uv run --with "openai-whisper" --with "pydub" --with "numpy" skills/audio-processing/tool.py transcribe --file_path input.wav uv run --with "openai-whisper" skills/audio-processing/tool.py transcribe --file_path input.wav --model small uv run --with "gTTS" skills/audio-processing/tool.py tts --text "Hello world" --output_path hello.mp3 uv run --with "librosa" --with "numpy" --with "soundfile" skills/audio-processing/tool.py extract_features --file_path input.wav uv run --with "pydub" skills/audio-processing/tool.py vad_segments --file_path input.wav uv run --with "pydub" skills/audio-processing/tool.py transform --file_path input.wav --ops '[{"op": "trim", "start": 10, "end": 30}, {"op": "normalize"}]' ``` ### Technical Analysis The Skill declares and installs multiple third-party packages without exact versions, a committed lock file, or package integrity hashes. The package names and installation sources shown in the audited files are not evidently malicious or typographically deceptive. However, unconstrained dependency resolution means the code ultimately executed can change after this Skill has been reviewed. A ...[truncated 1551 chars]
Remediation
## Remediation Suggestions 1. Pin every direct dependency to an exact, reviewed version instead of using unconstrained package names. 2. Generate and commit a lock file that records all transitive dependency versions for the supported environment. 3. Require cryptographic hashes for downloaded distributions where the package-management workflow supports them. 4. Install packages only from an explicitly configured trusted index, and prevent unintended fallback to untrusted or additional indexes. 5. Pin or otherwise control the FFmpeg installation version as well, because the current Homebrew declaration also resolves a mutable package version. 6. Use an automated dependency-update process that creates reviewable changes, runs security scanning and tests, and prevents unreviewed releases from entering production automatically. 7. Update every documented `uv run --with` example to use the same locked or exactly pinned dependency set as the Skill installation metadata. 8. Run the Skill and dependency installation in a least-privileged sandbox with restricted filesystem and network access to reduce the impact of a compromised package.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (8)

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises shell-based execution examples and requires external binaries, but it does not declare an explicit tool scope such as permissions or allowed-tools. In an agent environment, this can cause the skill to run with broader-than-necessary execution capability, increasing the chance of unintended command execution or misuse of shell access.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The TTS feature uses gTTS, which sends provided text to Google's external service, but the skill documentation does not warn users that their input leaves the local environment. This creates a data exposure risk if users supply secrets, private transcripts, or regulated content assuming processing is local.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The TTS path uses gTTS, which sends user-provided text to Google's network-backed service. That creates an undisclosed data egress path inconsistent with a skill described as audio processing, and sensitive prompts or private text could be transmitted to a third party without the caller realizing it.

Context-Inappropriate Capability

Medium
Confidence
85% confidence
Finding
Although audio transformation can reasonably involve ffmpeg, this implementation obtains that functionality by spawning an external process with subprocess.run. Executing host binaries is a stronger capability than ordinary in-process audio handling and is not declared in the manifest description, creating an intent/capability mismatch for a skill presented simply as audio processing.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd = ["ffmpeg", "-y"] + args
        # ffmpeg logs info to stderr
        process = subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        return True, process.stderr.decode()
    except subprocess.CalledProcessError as e:
        return False, e.stderr.decode()
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
User-supplied text is passed to gTTS without any disclosure that the content leaves the local environment and is processed by an external provider. This is a privacy and compliance risk because callers may provide secrets, personal data, or proprietary text under the assumption that processing is local.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The TTS implementation hard-codes lang='en', which imposes a specific language choice regardless of user preference. This is a natural-language policy issue because the skill does not offer opt-in language selection or explain why English-only output is required.

Natural-Language Policy Violations

Low
Confidence
86% confidence
Finding
The natural-language description fixes the TTS behavior to English by default and does not mention a user-selectable language or an opt-in mechanism. That can violate language/locale policy guidance when a skill imposes a language setting without clearly offering user choice.