Back to skill

Security audit

avavox 智能外呼

Security checks for vulnerabilities and agentic risk

Overview

This Avavox outbound-calling skill is mostly coherent, but it handles customer phone data and can make broad or misconfigured API changes that deserve review before installation.

Review this skill carefully before installing. Use a narrowly scoped Avavox App Key if available, avoid storing real keys in config.json, verify the final task line and call schedule before importing customers, and only upload customer phone numbers or ext fields when you have consent and are comfortable sending them to Avavox.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/avavox_call.py:431
Finding

Explicit Task Configuration Is Silently Overwritten by Stored Defaults

Content
View full analysis

Vulnerability Details

File Location: scripts/avavox_call.py, lines 431–450
Vulnerability Type: Improper configuration precedence
Risk Level: Medium

Vulnerable Code

python
assign_if_non_empty(body, "taskName", args.task_name)
assign_if_non_empty(body, "robotId", args.robot_id)
assign_if_non_empty(body, "lineId", args.line_id)
assign_if_non_empty(body, "backgroundAudio", args.background_audio)

concurrency = parse_optional_integer("concurrency", args.concurrency)
if concurrency is not None:
    body["concurrency"] = concurrency

assign_if_non_empty(body, "callTimeType", args.call_time_type)

if runtime_config is not None:
    body["runtimeConfig"] = runtime_config
if forbidden_call_time is not None:
    body["forbiddenCallTime"] = forbidden_call_time
if scheduled_time is not None:
    body["scheduledTime"] = scheduled_time

if mode == "create":
    assign_if_non_empty(body, "lineId", defaults.get("lineId"))
    assign_if_non_empty(body, "backgroundAudio", defaults.get("backgroundAudio"))
    assign_if_non_empty(body, "callTimeType", defaults.get("callTimeType"))

Technical Analysis

assign_if_non_empty() assigns every non-empty value without checking whether the destination key is already present. During task creation, explicit values supplied through command-line arguments or the base JSON body are written first. The creation branch then applies non-empty defaults to the same keys, overwriting the explicit values.

The affected fields are:

  • lineId
  • backgroundAudio
  • callTimeType

This reverses the expected configuration precedence. Defaults should serve only as fallbacks, while explicit user input should have priority.

The concurrency field is not affected because its default is applied only when "concurrency" not in body.

Attack Path

  1. A non-empty value is placed in defaults.lineId, defaults.backgroundAudio, or defaults.callTimeType through config.json or a supported environment variable.
  2. A use ...[truncated 1455 chars]
Remediation
View remediation

Remediation Suggestions

Apply defaults only when the corresponding field has not already been supplied:

python
if mode == "create":
    if "lineId" not in body:
        assign_if_non_empty(body, "lineId", defaults.get("lineId"))

    if "backgroundAudio" not in body:
        assign_if_non_empty(
            body,
            "backgroundAudio",
            defaults.get("backgroundAudio"),
        )

    if "callTimeType" not in body:
        assign_if_non_empty(
            body,
            "callTimeType",
            defaults.get("callTimeType"),
        )

    if "concurrency" not in body and defaults.get("concurrency") is not None:
        body["concurrency"] = parse_optional_integer(
            "defaults.concurrency",
            str(defaults["concurrency"]),
        )

Define and enforce a consistent precedence order, preferably:

  1. Explicit command-line arguments.
  2. Explicit body JSON, according to the documented merge policy.
  3. Environment or configuration defaults.

Add automated tests covering:

  • Explicit CLI values overriding defaults.
  • Explicit body values overriding defaults.
  • Defaults being used only when fields are absent.
  • Immediate and scheduled calling modes.
  • Conflicting values across CLI arguments, body JSON, environment variables, and config.json.
  • Verification of the final payload before the network request is sent.

For high-impact outbound actions, consider displaying the final resolved line and calling schedule for confirmation before task creation.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (11)

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.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill documents and enables capabilities that access environment variables, local files, and remote network endpoints, but it does not declare any explicit tool scope or permission boundaries. In an agent platform, this can lead to overbroad execution authority, making it easier for the skill to read secrets such as AVAVOX_APP_KEY, use local configuration files, and transmit data externally without a clear least-privilege contract.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs users to import customer phone numbers and variable data such as names and order identifiers into an external calling service, but it does not prominently warn that this transfers personal data off-platform. This creates privacy, compliance, and consent risks because users may bulk-upload sensitive customer data without understanding retention, processing, callback exposure, or legal obligations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file's natural-language instructions are fully presented in Chinese, and there is no indication that users may choose another language or that the skill is intended only for a Chinese-speaking or region-specific audience. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The examples include realistic-looking phone numbers together with Chinese personal names and explain how these values are passed through task variables and callbacks. In a voice-calling skill handling outbound campaigns, this normalizes processing of personal data without any privacy notice, masking guidance, or warning to avoid real customer data in docs and tests, which can lead to accidental exposure or non-compliant use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The customers import flow reads customer records containing required phoneNumber fields and POSTs them to the remote Avavox API. In this file there is no confirmation prompt, user-facing print/log message, or inline warning that sensitive customer data will be transmitted off-host.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest describes a skill for implementing voice outbound-calling scenarios such as batch calls, callbacks, surveys, interview screening, and reminders. The request handler accepts arbitrary HTTP methods, paths, query objects, and bodies for any /open/api endpoint, enabling use of unspecified Avavox API capabilities not limited to the described calling/task/customer operations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

SQP-3 applies to all file types and includes language or locale policy violations. This markdown file presents all operational guidance exclusively in Chinese, with no indication that the skill is region-specific or that users may choose another language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

该 markdown 文件以中文作为唯一说明语言,且未提供任何语言选择、双语说明或适用范围声明。根据规则,若技能在自然语言层面强制特定语言而没有用户 opt-in,可能构成语言/locale 政策违规。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

A file-wide natural-language policy issue exists because the skill documentation forces a single language/locale presentation without any opt-in or justification. The stated rule flags language or locale policy violations unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The request handler accepts arbitrary method, path, query, and body inputs and sends them to the Avavox API, but the code provides no confirmation, warning, or descriptive output before transmitting potentially sensitive payload data. Because this command is generic, users may not realize supplied body/query content is being sent remotely.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.