Back to skill

Security audit

Funasr Asr

Security checks for vulnerabilities and agentic risk

Overview

This speech-to-text skill is mostly purpose-aligned, but its wrapper can execute shell commands from user-controlled file paths and its video workflow accepts unrestricted URLs.

Review before installing. Use only trusted local media paths and trusted public video URLs, avoid running this skill with elevated privileges, and prefer an isolated environment. The package should replace shell-based exec with argument-array execution, validate URLs, and pin dependencies before broad use.

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

T09 · Insecure Skill Coding Practices

Error
Location
index.js:57
Finding

OS Command Injection in the Node.js Transcription Wrapper

Content
View full analysis
{ const scriptPath = path.join(__dirname, 'scripts', 'transcribe.py'); // 构建命令 let cmd = `python3 ${scriptPath} "${audioPath}"`; cmd += ` --mode ${modelMode}`; cmd += ` --format ${format}`; cmd += ` --segment ${segmentSeconds}`; if (verbose) cmd += ' --verbose'; if (noWait) cmd += ' --no-wait'; console.log(`[FunASR] 模式: ${modelMode}, 分段: ${segmentSeconds}s, 内存: ${modelMode === 'small' ? '~500MB' : '~2GB'}`); exec(cmd, { maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => { ``` ### Technical Analysis The `transcribe()` method constructs a command string by directly interpolating `audioPath`, `modelMode`, `format`, and `segmentSeconds`, then executes that string through `child_process.exec()`. The `exec()` API invokes a system shell, so shell metacharacters in any interpolated value are interpreted as command syntax. The preceding `fs.access(audioPath)` check does not neutralize this vulnerability. On supported filesystems, a real filename can contain quotes, command-substitution characters, semicolons, or other shell-significant characters. Additionally, direct callers of the exported `transcribe()` method are not constrained by the OpenClaw tool schema and can provide arbitrary option values. Quoting only `audioPath` with double quotes is insufficient because embedded double quotes and command substitutions can escape or remain active within the resulting shell command. ### Attack Path 1. An attacker gains control over a path or option passed to the exported `transcribe()` method. 2. The attacker supplies an existing audio filename containing shell syntax, or directly ...[truncated 966 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/video-transcribe.py:51
Finding

Server-Side Request Forgery Through Unrestricted Video and Web URLs

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/transcribe.py:86
Finding

Predictable Shared Lock Files Permit Symlink-Based File Corruption

Content
View full analysis
.lock` as a symbolic link to a file writable by the Skill's operating-system acco ...[truncated 916 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/install.sh:24
Finding

Unpinned Runtime Dependencies Create a Mutable Supply-Chain Risk

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (28)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code builds a shell command string with user-controlled audioPath and invokes it via exec(cmd, ...). Although the path is wrapped in double quotes, shell metacharacters such as command substitution can still be interpreted by the shell, enabling command injection and arbitrary command execution under the skill's privileges.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger list is very broad and includes generic speech-to-text scenarios such as any voice message, audio/video transcription, and even downloading web video for transcription. This can cause the skill to activate in many loosely related situations, increasing the chance of over-selection, unexpected tool use, or handling sensitive user media without sufficiently specific user intent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The natural-language descriptions and messages are presented only in Chinese, and the skill does not offer a language choice or explain a region-specific constraint. This can violate language/locale policy where skills must not force a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file title and all instructional content are written in Chinese, which imposes a specific language on users. Under the policy rules, locale or language constraints should either be optional for the user or clearly justified as region-specific; this document provides neither.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/memory-optimization.md (reported line 107)May include surrounding context.

bash
# 临时增加 swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/memory-optimization.md (reported line 108)May include surrounding context.

bash
# 临时增加 swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/memory-optimization.md (reported line 109)May include surrounding context.

bash
# 临时增加 swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/memory-optimization.md (reported line 110)May include surrounding context.

bash
# 临时增加 swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/memory-optimization.md (reported line 108)May include surrounding context.

bash
# 临时增加 swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's headings and instructions are entirely in Chinese, which can amount to a language/locale policy issue when no user opt-in or alternative language option is provided. The policy allows locale constraints only when they are explicitly offered as a choice or clearly justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script installs Python packages immediately and informs the user that large model downloads will occur later, but it does not ask for confirmation, pin versions, or document trusted sources. In a skill-installation context, unattended dependency and model retrieval increases supply-chain and unexpected network-execution risk, especially if users assume a purely local setup.

Content

No source excerpt is available for this finding.

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 79)May include surrounding context.

python
def get_duration(audio_path):
    """获取音频时长"""
    try:
        r = subprocess.run(
            ['ffprobe', '-i', audio_path, '-show_entries', 'format=duration',
             '-v', 'quiet', '-of', 'csv=p=0'],
            capture_output=True, text=True, timeout=10

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 169)May include surrounding context.

python
seg_path = os.path.join(tmpdir, f'seg_{i:03d}.wav')

        # ffmpeg 提取片段(16kHz mono PCM)
        subprocess.run([
            'ffmpeg', '-y', '-i', audio_path,
            '-ss', str(start), '-to', str(end),
            '-vn', '-acodec', 'pcm_s16le', '-ar', '16000', '-ac', '1',

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code presents its description, CLI help text, and operational messages in Chinese only, which is a natural-language locale constraint. Under the policy, a forced language without user opt-in or documented justification is a violation.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
86% confidence
Finding

This subprocess invocation executes an external downloader (yt-dlp) on a user-supplied URL. Although it avoids shell injection by passing an argument list to subprocess.run, it still enables untrusted input to drive network access and parsing in a powerful external binary, which can expose the host to SSRF-like internal access, unexpected protocol handling, or risk from vulnerabilities in the called tool.

Content

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

python
"-o", output_path,
                url
            ]
            subprocess.run(cmd, check=True, capture_output=True)
            print(f"✅ 视频已保存: {output_path}")
            return output_path
        except subprocess.CalledProcessError:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

This fallback subprocess executes ffmpeg -i <url> directly on a user-controlled URL. That allows ffmpeg to initiate arbitrary outbound connections and possibly access internal services or local/protected protocols depending on build configuration, making the context more dangerous than a normal local-file conversion step.

Content

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

python
# 回退到 ffmpeg
            try:
                cmd = ["ffmpeg", "-i", url, "-c", "copy", output_path, "-y"]
                subprocess.run(cmd, check=True, capture_output=True)
                print(f"✅ 视频已保存: {output_path}")
                return output_path
            except subprocess.CalledProcessError as e:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

This subprocess call invokes ffmpeg on media derived from untrusted input. There is no shell injection here, but processing attacker-controlled media with a complex parser like ffmpeg can lead to denial of service or exposure to parser/protocol vulnerabilities in the external tool.

Content

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

python
"-y",  # 覆盖输出文件
                output_path
            ]
            subprocess.run(cmd, check=True, capture_output=True)
            print(f"✅ 音频已提取: {output_path}")
            return output_path
        except subprocess.CalledProcessError as e:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The user-facing documentation is presented in Chinese, while the manifest advertises multilingual transcription capability and does not indicate that the documentation language is region-specific or optional. This can be a language/locale policy issue when users are not given a choice or notified of the locale assumption.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code comments and transcribe() logic indicate that a null mode should use the configuration file default, and the top-level description says it uses SenseVoiceSmall by default. However, the tool handler always passes params.mode || 'small', so configuration-based defaults are never honored through the exposed tool interface. This is an intent/documentation divergence within the code.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with a caret range (^4.1.0), which allows different patch and minor releases to be installed over time. This weakens build reproducibility and can unexpectedly pull in a vulnerable or behavior-changing version, especially for a skill that may process untrusted input formats like YAML.

Content

Scanner excerpt · package.json (reported line 36)May include surrounding context.

json
]
  },
  "dependencies": {
    "js-yaml": "^4.1.0"
  },
  "engines": {
    "node": ">=18.0.0"

Unverifiable Dependency: js-yaml has 11 known advisory(ies) (CVE-2026-84375 (js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources); GHSA-2pr6-76vf-7546 (Denial of Service in js-yaml); CVE-2026-59869 (js-yaml: YAML merge-key chains can force quadratic CPU consumption) +8 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
80% confidence
Finding

The manifest references js-yaml without pinning an exact version, while the package has a history of multiple advisories including denial-of-service conditions. In a skill ecosystem, YAML parsing often handles external configuration or content, so an unpinned package creates uncertainty about whether a vulnerable release could be installed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The guide states that the first run will automatically download model files and gives the cache location, but it does not clearly warn users about the practical security and operational implications such as network access, bandwidth consumption, disk usage growth, and potential privacy considerations from contacting external model registries. In an installation document, this omission can lead to unexpected downloads in restricted or metered environments, though it does not itself constitute active malicious behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file contains only Chinese-language headings and instructions, and does not provide any indication that the skill is intended exclusively for Chinese-speaking users or offer an alternative language option. Under the policy rule for natural-language violations, forcing a specific language without opt-in can be a locale-policy issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file documents fetching videos from YouTube, Bilibili, direct URLs, and other yt-dlp-supported sites, but it does not disclose that using the workflow will perform network retrieval of remote media. For markdown files, missing warnings about behaviors that may affect privacy or system/network activity should be flagged when omitted.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script's comments and user-visible messages are entirely in Chinese, including installation guidance and runtime behavior descriptions. For an all-file-types policy check, this is a language-policy issue because the skill enforces a specific language without user opt-in or any documented justification that it is intended only for a Chinese-speaking or region-specific context.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:36