Back to skill

Security audit

Asr Skill

Security checks for vulnerabilities and agentic risk

Overview

This speech-to-text skill is mostly purpose-aligned, but it exposes unauthenticated audio processing on all network interfaces and has under-disclosed webhook, URL, and alignment behavior.

Install only in a contained, local or private environment unless you first bind it to 127.0.0.1, add authentication and webhook signature verification, rate-limit and cap inference concurrency, reject arbitrary URLs and filesystem paths in webhook audio payloads, pin dependencies, and replace the broad pkill stop command with a skill-specific process stop mechanism.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
index.js:13
Finding

Unauthenticated Inference Service Exposed on All Network Interfaces

Content
View full analysis
{ // Request data is passed to an expensive Python inference process. const results = await PythonShell.run('asr.py', options); const result = results[0]; res.json(result); }); app.post('/align', upload.single('audio'), async (req, res) => { const results = await PythonShell.run('asr.py', options); const result = results[0]; res.json(result); }); app.post('/webhook', async (req, res) => { const { type, payload } = req.body; // Webhook processing occurs without authentication. }); app.listen(PORT, HOST, () => { console.log(`Service address: http://${HOST}:${PORT}`); }); ``` ### Technical Analysis The default host is `0.0.0.0`, which exposes the Express service through every available network interface. The computational endpoints `/transcribe`, `/align`, and `/webhook` do not implement authentication, authorization, webhook signature verification, rate limiting, request quotas, or inference concurrency controls. A request to `/transcribe` or `/align` can launch a Python process and invoke a multi-gigabyte machine-learning model. Although uploaded files have a 50 MB limit, that limit does not adequately constrain CPU time, decoded audio duration, model memory use, process count, or repeated requests. JSON requests are also accepted up to 50 MB. This is especially dangerous because the service is advertised as CPU-compatible and requires substantial memory. Multiple c ...[truncated 1323 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
index.js:266
Finding

Attacker-Controlled Webhook Audio Reference Reaches a URL-Capable Audio Loader

Content
View full analysis
{ try { const { type, payload } = req.body; switch (type) { case 'audio.message': const { audio, userId, sessionId, language } = payload; const normalizedLanguage = language ? dialectMap.normalize(language) : null; const transcribeResult = await new Promise((resolve, reject) => { const options = { mode: 'json', pythonPath: process.env.PYTHON_PATH || 'python3', scriptPath: __dirname, args: [ audio, '--device', modelConfig.device, '--dtype', modelConfig.dtype, ], }; if (normalizedLanguage) { options.args.push('--language', normalizedLanguage); } PythonShell.run('asr.py', options, (err, results) => { if (err) reject(err); else resolve(results[0]); }); }); ``` The Python implementation explicitly treats the value as a path or URL and forwards it to the model library: ```python def transcribe_audio( audio_input: str, language: Optional[str] = None, return_timestamps: bool = False, model_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Args: audio_input: audio path, URL, base64 data, or an array/sample-rate tuple """ if isinstance(audio_input, str) and audio_input.startswith('data:audio'): if ';base64,' in audio_input: audio_input = audio_input.split(';base64,')[1] audio_data = base64.b64decode(audio_input) audio_input = BytesIO(audio_data) ...[truncated 2400 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
skill.yml:209
Finding

Skill Stop Command Can Terminate Unrelated Node.js Applications

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:2
Finding

Mutable and Unlocked Third-Party Dependencies Create Supply-Chain Exposure

Content
View full analysis
=2.0.0 qwen-asr>=0.0.6 transformers>=4.37.0 accelerate>=0.26.0 sentencepiece>=0.1.99 protobuf>=4.25.0 torchaudio>=2.0.0 numpy>=1.24.0 ffmpeg-python>=0.2.0 ``` ```json "dependencies": { "express": "^4.18.2", "multer": "^1.4.5-lts.1", "axios": "^1.6.0", "python-shell": "^5.0.0", "dotenv": "^16.3.1" }, "devDependencies": { "nodemon": "^3.0.1" } ``` ```yaml install: steps: - name: Install Node.js dependencies command: npm install --only=production - name: Install Python dependencies command: pip install -r requirements.txt ``` No npm lockfile or hash-pinned Python dependency file is present in the supplied directory structure. ### Technical Analysis The Python requirements use lower-bound constraints, while the npm manifest uses compatible-version ranges. As a result, an installation performed after the audit may retrieve dependency versions that were not part of the reviewed artifact. The installation process does not verify Python package hashes and uses `npm install` rather than a lockfile-enforcing installation such as `npm ci`. Dependency installation and subsequent imports can execute package-controlled code. Large machine-learning dependency graphs also introduce many transitive components that are not fixed by the supplied manifests. This does not prove that any currently named dependency is malicious. The vulnerability is the lack of reproducibility and integrity enforcement, which expands the supply-chain attack surface and prevents the reviewed source from uniquely determining the installed runtime. ### Attack Path 1. An operator installs the Skill using the documented o ...[truncated 1220 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (97)

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 · DEVELOPER-GUIDE.md (reported line 59)May include surrounding context.

2. 配置环境变量

bash
cp .env.example .env
# 编辑 .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 · INSTALL.md (reported line 46)May include surrounding context.

2. 配置环境变量

bash
cp .env.example .env
# 编辑 .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 · README.md (reported line 33)May include surrounding context.

2. 配置环境变量

bash
cp .env.example .env
# 编辑 .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 · README.md (reported line 34)May include surrounding context.

bash
cp .env.example .env
# 编辑 .env 文件,根据需要调整配置

3. 启动服务

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

该代码与声明的主要用途存在明显不一致。声明强调这是一个语音转文字 Skill,但提供的代码仅负责 CPU 侧性能调优和模型优化辅助,包括线程设置、MKL-DNN、量化、预热以及返回模型配置。虽然配置中提到模型名 Qwen/Qwen3-ASR-0.6B,且 warmup 使用了类似音频特征形状的张量,但这只能说明代码可能是 ASR 系统的配套优化组件,而不是实现该 Skill 所宣称的核心识别能力本身。没有看到任何实际的音频输入处理、ASR 推理调用、文本输出、方言/多语言支持逻辑。因此应判定为描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述的核心能力是语音转文字、多语言/方言识别,这与代码中的/transcribe主功能基本一致。但代码还显式实现了若干未在描述中体现的能力:一是/align接口可进行音频与给定文本的强制对齐,这不属于单纯“语音转文字”;二是/webhook接口可接收并处理OpenClaw事件,不只是提供被动转写API,还包含skill启用/禁用事件处理;三是暴露/health和/info服务端点。虽然这些附加接口多数与ASR服务相关,但按照评估标准,属于未声明的能力与触发入口,因此应判定为描述与实际行为存在不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个语音识别 Skill 的功能能力,但给出的代码片段仅是 package.js 打包辅助脚本。它访问本地文件系统检查 skills/qwen-asr-skill 目录和 SKILL.md、index.js、package.json 是否存在,然后打印发布说明,没有处理音频输入、调用 ASR 模型、执行转写、或提供任何与方言识别相关的实现。因此代码实际行为与声明的主要目的存在明显不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

核心功能与声明大体一致:代码确实围绕 Qwen ASR 做语音转文字,并支持多语言/方言输入,也与 OpenClaw 集成。但代码还实现了一个独立的强制对齐能力,需要输入文本和语言,将音频与文本进行对齐,这属于实质性的额外能力,声明中未提及。此外,代码不只是一个内部转写模块,还公开了多个 HTTP API 与 webhook 事件处理接口。健康检查和信息接口可视为支持性实现细节,不单独构成问题;但 /align 属于明显的未声明能力,因此应判定为描述与实际行为存在不匹配。

Content

No source excerpt is available for this finding.

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 · clawdhub.md (reported line 28)May include surrounding context.

  1. 打包项目文件:

    bash
    zip -r qwen-asr-skill.zip . -x "models/*" "uploads/*" "node_modules/*" "__pycache__/*" "*.log" ".env" ".git/*"
    
  2. 访问 ClawdHub官网,登录你的账号

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file uses only Chinese for all user-facing natural language, including headings and release notes. Under the policy rule for language/locale, forcing a specific language without user opt-in or a documented regional justification is a policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This markdown file presents the developer guidance exclusively in Chinese, starting with the title and continuing throughout the document. Under the policy rule, forcing a specific language without user opt-in or justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · INSTALL.md (reported line 35)May include surrounding context.

bash
# 创建conda环境
conda create -n qwen-asr python=3.12 -y
conda activate qwen-asr

# 安装依赖

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · INSTALL.md (reported line 35)May include surrounding context.

bash
# 创建conda环境
conda create -n qwen-asr python=3.12 -y
conda activate qwen-asr

# 安装依赖

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The test instructions tell users to upload audio files to the transcription service without warning that voice recordings may contain sensitive personal, biometric, or confidential information. In a speech-recognition skill, this context makes the omission more significant because the primary input is user voice data, which may be retained in logs, temp files, or mounted storage.

Content

No source excerpt is available for this finding.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

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

md
formData.append('audio', fs.createReadStream('audio.wav'));
formData.append('language', 'Sichuan'); // 指定四川方言

axios.post('http://localhost:3000/transcribe', formData, {
  headers: formData.getHeaders()
})
.then(response => {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README states that user voice messages are automatically processed by the skill and forwarded into the OpenClaw pipeline, but it does not disclose how audio is stored, transmitted, retained, or protected. For a voice-processing skill, this omission is security- and privacy-relevant because speech may contain sensitive personal data, and users or operators are not warned about handling requirements.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The code explicitly documents and forwards audio_input as a path, URL, base64 blob, or stream into the model without any validation or warning, which can enable unintended network access if downstream libraries dereference URLs. In a skill advertised as local speech recognition, this can expose the host to SSRF-style requests, privacy leaks, or unexpected outbound traffic when a user supplies a crafted URL.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Manifest description focuses on speech-to-text for dialect and multilingual recognition, but this file also exposes a separate forced-alignment workflow that aligns provided text against audio. Forced alignment is a distinct capability beyond ordinary ASR transcription and is not mentioned in the skill description.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code file contains user-facing natural-language text exclusively in Chinese in the module docstring and later print messages, with no indication that the user can choose another language. The policy specifically flags language or locale constraints when they are imposed without opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

This JavaScript file uses Chinese-only natural-language comments and dialect labels throughout, indicating a language-specific skill experience without any visible opt-in or justification for restricting locale. Under the policy, forcing a specific language without user choice can be a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes this skill as a speech-to-text capability for dialect and multilingual recognition. However, the code exposes a separate /align endpoint for forced audio-text alignment, requiring input text and performing a different operation than transcription. This is a meaningful expansion of behavior beyond the described ASR-only purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The /webhook handler accepts audio-related payload data, invokes transcription, and returns transcribed text along with userId and sessionId. Although this behavior is core functionality, there is no visible user disclosure, confirmation, or privacy warning in this file about handling and transmitting user audio and associated identifiers through the webhook flow.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.