Back to skill

Security audit

Voice Ai Integration

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for Shengwang voice and RTC integration, but it needs review because its token-server and remote-document guidance can create real security exposure if followed as-is.

Review before installing. If used, do not deploy the token endpoint as written: require caller authentication, authorize channel and UID server-side, avoid wildcard and publisher-by-default tokens, shorten expirations, and add rate limits. Treat fetched docs and cloned samples as untrusted until reviewed, pin or verify token-builder source, keep all secrets server-side, and add consent and retention controls before enabling recording.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T09 · Insecure Skill Coding Practices

Error
Location
references/token-server/README.md:46
Finding
Unauthenticated and Over-Privileged RTC Token Issuance<![CDATA[ ## Vulnerability Details **File Location**: `references/token-server/README.md`, lines 46–77 and 109–113 **Vulnerability Type**: Missing endpoint authentication and excessive token privileges **Risk Level**: High ### Vulnerable Code ```markdown ### Step 3: Implement Token Endpoint Create a `GET /api/agora/token` endpoint. **Request parameters:** | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `channelName` | string | Yes | — | RTC channel name. `""` for wildcard (any channel). | | `uid` | integer | No | `0` | User ID. `0` = wildcard (any user). | | `role` | string | No | `publisher` | `publisher` (send+receive) or `subscriber` (receive only) | | `expireSeconds` | integer | No | `3600` | Token validity in seconds. Max: 86400 (24h). | **Response:** Plain text token string. | Status | Meaning | |--------|---------| | 200 | Token generated | | 400 | Missing `channelName` | | 500 | Generation failed | **Example:** ```bash curl "http://localhost:8080/api/agora/token?channelName=test&uid=12345&role=publisher&expireSeconds=3600" ``` ``` ```markdown ### Wildcard Tokens - `uid = 0` → works for any UID - `channelName = ""` → works for any channel - Both wildcard → single token for any user in any channel (use with caution) ``` ### Technical Analysis The generated token-server specification does not require callers to authenticate before obtaining a signed RTC token. It also allows caller-controlled channel names, UIDs, roles, and expiration periods. The default role is `publisher`, which grants send and receive capabilities. The documented wildcard behavior permits tokens valid for arbitrary users or channels. Although the text says to use wildcard tokens with caution, it does not require privileged authorization or disable this behavior by default. The token endpoint therefore acts as an unrestricted signing oracle if it is deployed where an attacker can reach it. The App Certifica ...[truncated 1277 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require application-level authentication before issuing any token. 2. Authorize each request against the authenticated user's permitted channels and capabilities. 3. Derive the UID, channel, and role from trusted server-side session state instead of accepting unrestricted client-selected values. 4. Default to subscriber or the minimum necessary privileges rather than publisher. 5. Disable empty-channel and wildcard-UID tokens by default. 6. Place wildcard issuance behind a separate administrative authorization path if it is operationally necessary. 7. Use fine-grained privilege tokens and grant only required capabilities such as channel join, audio publication, video publication, or data-stream publication. 8. Enforce a short server-controlled expiration limit instead of trusting the requested value. 9. Apply rate limiting, abuse monitoring, restrictive CORS rules, and security audit logging. 10. Prefer an authenticated `POST` endpoint and return tokens with `Cache-Control: no-store`. 11. Update the Skill guidance so generated implementations must include these controls rather than leaving them as optional production hardening. ]]>

T08 · Insecure Dependencies

Warning
Location
references/token-server/README.md:21
Finding
Unpinned Remote Cryptographic Source Is Copied into Generated Projects<![CDATA[ ## Vulnerability Details **File Location**: `references/token-server/README.md`, lines 21–44 **Vulnerability Type**: Unverified mutable source dependency **Risk Level**: Medium ### Vulnerable Code ```markdown ### Step 2: Get AgoraDynamicKey All language implementations live in one repo: `https://github.com/AgoraIO/Tools` > ⚠️ **DO NOT** use `agora-token-builder`, `agora-token`, or any third-party token package from PyPI / npm / Maven. > These are unofficial, outdated, and may generate incompatible tokens (v1 instead of v2). > The ONLY supported source is the official [AgoraDynamicKey](https://github.com/AgoraIO/Tools) repo below. Clone the repo: ```bash git clone --depth 1 https://github.com/AgoraIO/Tools.git ``` After download, find your language under `Tools/DynamicKey/AgoraDynamicKey/<language>/src/`: | Language | Source path | Builder file | |----------|------------|--------------| | Go | `go/src/rtctokenbuilder2/` | `RtcTokenBuilder2.go` | | Java | `java/src/main/java/io/agora/media/` | `RtcTokenBuilder2.java` | | Python3 | `python3/src/` | `RtcTokenBuilder2.py` | | Node.js | `nodejs/src/` | `RtcTokenBuilder2.js` | | PHP | `php/src/` | `RtcTokenBuilder2.php` | | C++ | `cpp/src/` | `RtcTokenBuilder2.h` | > Go projects: copy `rtctokenbuilder2` source files into your project. The Tools repo is not a standalone Go module. ``` ### Technical Analysis The Skill instructs users to clone the current default branch of a remote repository and copy token-generation source into their applications. The command is not pinned to a reviewed commit or signed release, and no checksum, signature, or source verification step is required. HTTPS protects the connection to GitHub but does not make repository contents immutable. A compromised upstream account, repository, or future unsafe commit could change the code retrieved after this Skill has been audited. This is especially sensitive because the copied component performs cryptographic token generation ...[truncated 1185 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the dependency to a specific reviewed commit hash or signed release tag. 2. Publish the expected commit and SHA-256 checksums in the Skill. 3. Verify release signatures or checksums before copying or executing source. 4. Use a detached checkout after cloning, for example: ```bash git clone --filter=blob:none https://github.com/AgoraIO/Tools.git cd Tools git checkout --detach <reviewed-commit-hash> ``` 5. Document the exact required files and expected hashes for each supported language. 6. Require a source review before copying files that will process the App Certificate. 7. Prefer an official, versioned, integrity-verifiable package or release artifact where available. 8. Add dependency monitoring and periodically review the pinned revision for security fixes. 9. Never automatically update the cryptographic component from the remote default branch during application startup or deployment. ]]>

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:18
Finding
Mutable Remote Documentation Is Trusted Without Integrity or Prompt-Boundary Controls<![CDATA[ ## Vulnerability Details **File Locations**: - `SKILL.md`, lines 18–28 and 121–128 - `references/doc-fetching.md`, lines 5–35 - `scripts/fetch-docs.sh`, lines 7–15 - `scripts/fetch-doc-content.sh`, lines 20–23 **Vulnerability Type**: Remote content trust and indirect instruction-injection risk **Risk Level**: Medium ### Vulnerable Code From `SKILL.md`: ```markdown ### Step 0: Ensure doc index exists (MANDATORY) > **⚠️ Execute this BEFORE any routing or code generation.** Check if `references/docs.txt` already exists. If it does, skip this step entirely. If it does not exist, download it: ```bash bash skills/voice-ai-integration/scripts/fetch-docs.sh ``` This downloads a static doc index from `doc.shengwang.cn` — no user data is sent. If download fails, proceed with local reference docs and fallback URLs. ``` ```markdown Network behavior: - `fetch-docs.sh` downloads a static file from `doc.shengwang.cn/llms.txt` — no user data is sent - `fetch-doc-content.sh` fetches a single doc page by URI from `doc-mcp.shengwang.cn` — only the doc URI is sent, no user context ``` From `scripts/fetch-docs.sh`: ```bash DOCS_URL="https://doc.shengwang.cn/llms.txt" SCRIPT_DIR="$(dirname "$0")" OUTPUT_FILE="${SCRIPT_DIR}/../references/docs.txt" MAX_RETRIES=3 for i in $(seq 1 $MAX_RETRIES); do echo "Downloading doc index (attempt ${i}/${MAX_RETRIES}) ..." if curl -fSL --retry 2 --max-time 120 -o "${OUTPUT_FILE}" "${DOCS_URL}"; then ``` From `scripts/fetch-doc-content.sh`: ```bash DOC_URI="$1" BASE_URL="https://doc-mcp.shengwang.cn/doc-content-by-uri" FULL_URL="${BASE_URL}?uri=${DOC_URI}" if ! curl -fSL --max-time 30 --retry 2 "$FULL_URL" 2>/dev/null; then ``` From `references/doc-fetching.md`: ```markdown ## Step 1: Ensure doc index exists Check if `references/docs.txt` exists. If not, download it: ```bash bash skills/voice-ai-integration/scripts/fetch-docs.sh ``` ## Step 2: Find the document URI Search `references/docs.txt` for keywords. Each entry f ...[truncated 2485 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Explicitly state that all remotely fetched documentation is untrusted reference data. 2. Instruct the Agent to ignore remote text that attempts to change system rules, Skill goals, safety constraints, credential handling, or tool permissions. 3. Prohibit execution of commands obtained solely from remote documentation without local validation and user approval. 4. Pin the documentation index to a reviewed version and verify a published checksum or digital signature. 5. Download to a temporary file, validate it, and atomically replace `references/docs.txt` only after successful verification. 6. Validate document URIs against a strict allowlist such as: ```text ^docs://default/(convoai|rtc|rtm2|cloud-recording)/[A-Za-z0-9._~/-]+$ ``` 7. URL-encode the URI query parameter instead of direct string concatenation, for example with `curl --get --data-urlencode`. 8. Restrict redirects to HTTPS and verify that the final host remains in an explicit allowlist. 9. Set reasonable response-size limits and validate that responses are expected text or Markdown. 10. Record provenance, retrieval time, digest, and final URL for fetched content. 11. Require explicit user consent before fetching remote documentation when local references are sufficient. 12. Remove the unconditional “MANDATORY” fetch requirement or limit it to tasks that actually require current remote documentation. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (41)

Credential Access

High
Category
Privilege Escalation
Content
| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `token` | string | yes | Volcengine access token |
| `app_id` | string | yes | Volcengine app ID |
| `voice_type` | string | yes | e.g. `BV700_streaming` |
| `cluster` | string | no | e.g. `volcano_tts` |
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill instructs the agent to execute shell commands and perform network downloads, but it does not declare any explicit tool scope or allowed-tools boundary. That creates a capability mismatch where an agent runtime may permit broader shell use than intended, increasing the risk of arbitrary command execution, unexpected external access, or unsafe follow-on actions if the skill is invoked in the wrong context.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger description is very broad and includes generic terms such as AI agent, recording, token, video call, and live streaming, which can cause the skill to activate for unrelated requests. Because the skill can then drive shell-based doc fetching and routing decisions, unintended invocation expands the attack surface and may lead to unnecessary network activity or execution of privileged workflow steps.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This README promotes server-side recording of RTC audio/video to cloud storage but does not mention consent, notification, retention, or legal/privacy obligations. In a developer-facing integration skill, that omission can lead users to deploy recording features that capture conversations without appropriate disclosure or authorization, creating privacy and compliance risk.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The README instructs users that Quickstart requires an App ID and App Certificate and points to token/auth flows, but it does not warn that the App Certificate is a sensitive secret that must never be embedded in client code, committed to repositories, or exposed in logs. In a voice/RTC integration skill, this omission can lead users to handle credentials insecurely during setup, enabling token forgery or unauthorized use of Shengwang services if the certificate leaks.

External Transmission

Medium
Category
Data Exfiltration
Content
def create_agent_with_retry(payload, max_retries=3):
    for attempt in range(max_retries):
        resp = requests.post(url, json=payload, headers=headers)
        if resp.status_code in (200, 201):
            return resp.json()
        if resp.status_code in (503, 504):
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The file describes an interrupt endpoint whose purpose is to stop an agent from speaking or thinking, but the response text says the returned agent information means 'the agent starts broadcasting specified content.' That is an active contradiction in the documentation, not merely an omission, and could mislead integrators about the side effects of calling this API.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
This is a markdown file, so SQP-2 applies to missing warnings in the skill description. The document explains that requests can interrupt the agent immediately and even set `interruptable` to `false`, but it presents these as features without a caution about user experience, conversation disruption, or non-interruptible playback.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
This markdown file documents a configuration-changing API that can materially alter a running agent's behavior. Although it notes that the field will overwrite the creation-time configuration, it does not clearly warn users about the operational impact or advise caution before making the change.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The document includes a directly usable Basic Auth credential construction pattern using customer key and secret, but it does not warn readers to treat these values as secrets, avoid embedding them in client-side code, or store them securely. In API integration documentation, this omission can lead developers to copy the pattern into insecure contexts, increasing the risk of credential exposure and unauthorized API access.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This markdown file documents an API that returns stored short-term memory, including user and assistant messages. Because the operation exposes potentially sensitive conversation history, the documentation should include a clear privacy warning or handling guidance for users.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This markdown file describes sending authentication material in the `Authorization` header, including RTC Token and Basic Auth examples, but it does not include any warning about treating these values as sensitive credentials. For markdown files, SQP-2 applies when descriptions omit warnings about behaviors affecting privacy or system integrity; credential handling is security-sensitive and should be explicitly cautioned.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The entire skill document, including title, description, and operational instructions, is presented only in Chinese. This can constitute a language/locale policy violation because it imposes a specific language without user opt-in and does not document a justified region-specific constraint.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
Line L046 defines `properties.asr.language` with a default of `"zh-CN"` and presents language handling as a fixed default rather than a user-selected preference. Under the policy rule, forcing a specific language or locale without explicit opt-in is a natural-language policy concern unless clearly justified as region-specific.

External Transmission

Medium
Category
Data Exfiltration
Content
"enable_aivad": true
    },
    "llm": {
      "url": "https://api.minimax.chat/v2/text/chatcompletion_v2",
      "api_key": "xxx",
      "system_messages": [
        {
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
"enable_aivad": true
    },
    "llm": {
      "url": "https://api.minimax.chat/v2/text/chatcompletion_v2",
      "api_key": "xxx",
      "system_messages": [
        {
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
"enable_aivad": true
    },
    "llm": {
      "url": "https://api.minimax.chat/v2/text/chatcompletion_v2",
      "api_key": "xxx",
      "system_messages": [
        {
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
}
    },
    "llm": {
      "url": "https://api.openai.com/v1/chat/completions",
      "api_key": "your_openai_api_key",
      "system_messages": [
        {
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The natural-language content, including the title, description, and operational instructions, is fixed to Chinese. Under the policy, forcing a specific language without user opt-in or a documented regional justification is a locale-policy issue.

External Transmission

Medium
Category
Data Exfiltration
Content
## 服务器

- `https://api.agora.io/cn/api/conversational-ai-agent`
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## 服务器

- `https://api.agora.io/cn/api/conversational-ai-agent`
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## 服务器

- `https://api.agora.io/cn/api/conversational-ai-agent`
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## 服务器

- `https://api.agora.io/cn/api/conversational-ai-agent`
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## 服务器

- `https://api.agora.io/cn/api/conversational-ai-agent`
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
## 服务器

- `https://api.agora.io/cn/api/conversational-ai-agent`
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.