Back to skill

Security audit

Speech to Text (Yandex SpeechKit)

Security checks for vulnerabilities and agentic risk

Overview

This is a speech-to-text skill that uses Yandex SpeechKit as advertised, with privacy and dependency hygiene considerations but no evidence of malicious behavior.

Before installing, understand that voice audio will be sent to Yandex SpeechKit for transcription. Prefer storing credentials through OpenClaw's skill environment configuration, use a narrowly scoped Yandex API key, avoid running diagnostics on shared hosts where process arguments may be logged, and consider pinning dependencies for higher-assurance deployments.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T08 · Insecure Dependencies

Warning
Location
requirements.txt:2
Finding

Automatic Installation of Unpinned and Unhashed Dependencies

Content
View full analysis
=1.0.0 requests>=2.31.0 urllib3>=1.26.0 ``` ```bash # setup.sh:19-20 echo "Installing Python dependencies..." .venv/bin/pip install --quiet -r requirements.txt ``` ### Technical Analysis The dependency declarations use open-ended minimum-version constraints. They do not pin reviewed versions, constrain maximum versions, or provide cryptographic hashes. Consequently, each execution of `setup.sh` may resolve and install dependency releases that did not exist when the skill was audited. Python package installation can execute package build or installation logic. If a permitted package release, transitive dependency, configured package index, or package resolution process is compromised, running the setup script can introduce and execute attacker-controlled code. This finding does not establish that any currently declared package is malicious. It identifies an unsafe dependency-management process that leaves future installations dependent on mutable external package state. ### Attack Path 1. An attacker compromises a permitted direct or transitive dependency release, or the package source used by pip. 2. The compromised release still satisfies one of the open-ended version constraints. 3. A user installs or updates the skill and runs `bash setup.sh`. 4. Pip resolves the compromised version and downloads it. 5. Malicious build or installation logic executes with the privileges of the user running the setup script. 6. The installed package can subsequently execute whenever the STT scripts import it. ### Impact Assessment Successful exploitation could execute arbitrary code with the privileges of the account running `setup.sh`. Within those privileges, an attacker could access skill dat ...[truncated 289 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/audio_processor.py:349
Finding

Predictable Shared Temporary Audio Filenames Permit Request Collisions

Content
View full analysis
str: """ Generate a temporary filename based on the original file path. Args: original_path: Original file path extension: Extension for the new file Returns: str: Path to the temporary file """ original_name = Path(original_path).stem timestamp = int(time.time()) temp_name = f"{original_name}_{timestamp}.{extension}" temp_dir = tempfile.gettempdir() temp_path = os.path.join(temp_dir, "stt_audio", temp_name) os.makedirs(os.path.dirname(temp_path), exist_ok=True) logger.debug(f"Generated temp filename: {temp_path}") return temp_path ``` ```python # scripts/providers/yandex_speechkit.py:221-228 temp_ogg_path = self.audio_processor.generate_temp_filename(audio_file_path, "ogg") try: ogg_path = self.audio_processor.convert_to_ogg_opus(audio_file_path, temp_ogg_path) with open(ogg_path, 'rb') as f: audio_data = f.read() logger.debug(f"Conversion complete, size: {len(audio_data)} bytes") return audio_data, 'oggopus' finally: self.audio_processor.cleanup_temp_file(temp_ogg_path) ``` The conversion command also includes unconditional overwrite behavior: ```python cmd = [ 'ffmpeg', '-i', input_file, '-ar', '48000', '-ac', '1', '-c:a', 'libopus', '-y', output_file ] ``` ### Technical Analysis Temporary output names are derived only from the source basename and a timestamp with one-second resolution. Two requests processing files with the same basename during the same second therefore derive the same output path. The p ...[truncated 1694 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
check.sh:227
Finding

Diagnostic Curl Invocation Places the API Key in Process Arguments

Content
View full analysis
/dev/null || echo "000") ``` ### Technical Analysis The shell expands `${CHECK_API_KEY}` before starting curl. The resulting plaintext authorization header becomes part of curl's argument vector for the duration of the request. Depending on operating-system process visibility, account boundaries, monitoring agents, diagnostic tooling, and process auditing configuration, command-line arguments may be observable through process inspection interfaces or collected in operational telemetry. Redirecting curl output does not remove the key from its process arguments. The request is sent to the documented Yandex SpeechKit HTTPS endpoint, and no evidence was found that the script intentionally transmits the credential to an unrelated host. The weakness is local exposure of the credential while performing the legitimate connectivity check. ### Attack Path 1. A user configures valid Yandex credentials and runs `bash check.sh`. 2. The script copies the API key into `CHECK_API_KEY`. 3. The shell expands the key into curl's `-H` argument. 4. Curl runs with the plaintext key present in its process argument vector. 5. A local process observer or monitoring system capable of reading command-line arguments captures the header. 6. The observer extracts and reuses the API key against Yandex services permitted by that credential. ### Impact Assessment An attacker who obtains the key may make unauthorized API requests within the key's Yandex Cloud permissions, consume service quota, incur costs, or access other services authorized for ...[truncated 277 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (51)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description explains that audio is converted to text using Yandex SpeechKit, but it does not clearly and prominently warn that voice content is sent to an external cloud service. This creates a privacy and compliance risk because users may assume processing is local while sensitive voice data is actually transmitted off-system.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · README.md (reported line 33)May include surrounding context.

brew install ffmpeg

Ubuntu / Debian

sudo apt update && sudo apt install -y ffmpeg

Windows — download from https://ffmpeg.org/download.html and add to PATH

text

Credential Access

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

The development instructions explicitly tell contributors to edit a local .env file with credentials inside the repository working tree. This increases the risk of accidental secret leakage through commits, backups, shell history, or local file exposure, especially in a shared development environment.

Content

Scanner excerpt · README.md (reported line 306)May include surrounding context.

git clone https://github.com/bzSega/sergei-mikhailov-stt.git cd sergei-mikhailov-stt bash setup.sh

Edit .env with your credentials

text

Please follow PEP 8 and add docstrings to all public functions. Pull requests are welcome.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 145)May include surrounding context.

sh
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 155)May include surrounding context.

sh
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 170)May include surrounding context.

sh
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 182)May include surrounding context.

sh
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 192)May include surrounding context.

sh
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/config_manager.py (reported line 22)May include surrounding context.

python
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/config_manager.py (reported line 236)May include surrounding context.

python
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · setup.sh (reported line 25)May include surrounding context.

sh
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · setup.sh (reported line 27)May include surrounding context.

sh
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · setup.sh (reported line 33)May include surrounding context.

sh
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · setup.sh (reported line 35)May include surrounding context.

sh
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · setup.sh (reported line 53)May include surrounding context.

sh
from dotenv import load_dotenv

# Load .env only from the skill root directory (parent of scripts/),
# not from an arbitrary working directory.
_skill_root = Path(__file__).resolve().parent.parent
_dotenv_path = _skill_root / ".env"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 146)May include surrounding context.

sh
.venv/bin/pip install --quiet -r requirements.txt

# 2. Configuration files
if [ ! -f ".env" ]; then
    if [ -f "assets/env.example" ]; then
        cp assets/env.example .env
    else

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 147)May include surrounding context.

sh
.venv/bin/pip install --quiet -r requirements.txt

# 2. Configuration files
if [ ! -f ".env" ]; then
    if [ -f "assets/env.example" ]; then
        cp assets/env.example .env
    else

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 148)May include surrounding context.

sh
.venv/bin/pip install --quiet -r requirements.txt

# 2. Configuration files
if [ ! -f ".env" ]; then
    if [ -f "assets/env.example" ]; then
        cp assets/env.example .env
    else

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 152)May include surrounding context.

sh
.venv/bin/pip install --quiet -r requirements.txt

# 2. Configuration files
if [ ! -f ".env" ]; then
    if [ -f "assets/env.example" ]; then
        cp assets/env.example .env
    else

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 193)May include surrounding context.

sh
.venv/bin/pip install --quiet -r requirements.txt

# 2. Configuration files
if [ ! -f ".env" ]; then
    if [ -f "assets/env.example" ]; then
        cp assets/env.example .env
    else

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 194)May include surrounding context.

sh
.venv/bin/pip install --quiet -r requirements.txt

# 2. Configuration files
if [ ! -f ".env" ]; then
    if [ -f "assets/env.example" ]; then
        cp assets/env.example .env
    else

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · check.sh (reported line 195)May include surrounding context.

sh
.venv/bin/pip install --quiet -r requirements.txt

# 2. Configuration files
if [ ! -f ".env" ]; then
    if [ -f "assets/env.example" ]; then
        cp assets/env.example .env
    else

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/config_manager.py (reported line 25)May include surrounding context.

python
.venv/bin/pip install --quiet -r requirements.txt

# 2. Configuration files
if [ ! -f ".env" ]; then
    if [ -f "assets/env.example" ]; then
        cp assets/env.example .env
    else

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/config_manager.py (reported line 190)May include surrounding context.

python
.venv/bin/pip install --quiet -r requirements.txt

# 2. Configuration files
if [ ! -f ".env" ]; then
    if [ -f "assets/env.example" ]; then
        cp assets/env.example .env
    else

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · setup.sh (reported line 23)May include surrounding context.

sh
.venv/bin/pip install --quiet -r requirements.txt

# 2. Configuration files
if [ ! -f ".env" ]; then
    if [ -f "assets/env.example" ]; then
        cp assets/env.example .env
    else

Static analysis

No suspicious patterns detected.