Back to skill

Security audit

Voice.Ai Voice Agents

Security checks for vulnerabilities and agentic risk

Overview

The skill’s core purpose is coherent, but it can change or delete live Voice.ai resources and has weak safeguards around API-key handling.

Review before installing. Use a narrowly scoped Voice.ai API key, do not run the documented echo command for the key, avoid committing .env files, and require explicit confirmation before deploy, delete, knowledge-base deletion, or phone-number changes. Prefer the default HTTPS endpoint unless you have separately verified a custom endpoint is trusted.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:52
Finding
API Key Disclosed Through Terminal Output<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 52–57 **Vulnerability Type**: Plaintext credential exposure **Risk Level**: Medium ### Vulnerable Code ```bash # 1. Check if API key is set echo $VOICE_AI_API_KEY # 2. Test connection (list agents) node scripts/agent.js list ``` ### Technical Analysis The documented authentication verification procedure prints the complete value of `VOICE_AI_API_KEY` to standard output. This is a bearer credential, so possession of its value may be sufficient to authenticate to the Voice.ai API. Terminal output can be retained in CI/CD logs, command transcripts, support bundles, shell recordings, remote administration sessions, or screen-sharing recordings. Printing the credential is unnecessary because authentication can be checked without exposing its value. ### Attack Path 1. A user follows the documented pre-operation instructions. 2. `echo $VOICE_AI_API_KEY` writes the complete API key to the terminal. 3. The output is captured by a log collector, terminal recorder, screen-sharing session, or another person with access to the terminal output. 4. An attacker extracts the bearer token. 5. The attacker submits authenticated requests to the Voice.ai API using the exposed token. This path requires the attacker to obtain access to the terminal output or a system that records it. ### Impact Assessment A disclosed token may grant the attacker all permissions assigned to the affected Voice.ai API key. Depending on those permissions, the attacker could inspect account resources, access agent or call-related information, create or modify agents, deploy or pause agents, disable agents, and manage other API-backed resources. The precise scope is limited by the server-side permissions associated with the compromised key. This issue does not directly grant local operating-system privileges or arbitrary code execution. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions Do not print the API key during configuration checks. Test only whether the variable is present: ```bash if [ -n "${VOICE_AI_API_KEY:-}" ]; then echo "VOICE_AI_API_KEY is configured" else echo "VOICE_AI_API_KEY is missing" fi ``` Additional hardening measures: 1. Remove `echo $VOICE_AI_API_KEY` from all documentation and setup scripts. 2. Redact bearer tokens from application, proxy, and CI/CD logs. 3. Avoid enabling shell tracing with `set -x` while handling secrets. 4. Use a dedicated secret manager where available. 5. Assign the API key only the minimum required server-side permissions. 6. Rotate the API key immediately if it has already appeared in retained logs or shared terminal output. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
voice-ai-agents-sdk.js:100
Finding
Bearer Token Can Be Transmitted to an Arbitrary Host or Over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `voice-ai-agents-sdk.js`, lines 100–125 **Vulnerability Type**: Unrestricted authentication destination and insecure transport **Risk Level**: Medium ### Vulnerable Code ```javascript constructor(apiKey, options = {}) { if (!apiKey) { throw new AuthenticationError('API key is required'); } this.apiKey = apiKey; this.baseUrl = options.baseUrl || API_BASE_URL; this.timeout = options.timeout || 30000; } // ========================================================================== // Private Methods // ========================================================================== /** * Make an HTTP request to the API * @private */ _request(method, path, body = null) { return new Promise((resolve, reject) => { const url = new URL(`/api/${API_VERSION}${path}`, this.baseUrl); const isHttps = url.protocol === 'https:'; const httpModule = isHttps ? https : http; const options = { hostname: url.hostname, port: url.port || (isHttps ? 443 : 80), path: url.pathname + url.search, method: method, headers: { 'Authorization': `Bearer ${this.apiKey}`, ``` ### Technical Analysis The SDK accepts an unrestricted `options.baseUrl`, supports both HTTP and HTTPS, and unconditionally attaches the Voice.ai API key as an `Authorization: Bearer` header. No validation requires the destination to use HTTPS, and no host allowlist limits authentication to an expected Voice.ai domain. Consequently, a caller that supplies an untrusted base URL can cause the SDK to disclose the token directly to another host. If an HTTP URL is supplied, the token is also vulnerable to interception or modification by an attacker with access to the network path. The bundled CLI does not expose a base URL argument and uses the default HTTPS endpoint. Exploitation therefore requires another SDK consumer, configuration layer, or compromised integration to provide an unsafe `options.ba ...[truncated 1543 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Require TLS before storing or transmitting the credential: ```javascript const parsedBaseUrl = new URL(options.baseUrl || API_BASE_URL); if (parsedBaseUrl.protocol !== 'https:') { throw new ValidationError('The API base URL must use HTTPS'); } if (parsedBaseUrl.username || parsedBaseUrl.password) { throw new ValidationError('Credentials are not permitted in the API base URL'); } const allowedHosts = new Set(['dev.voice.ai']); if (!allowedHosts.has(parsedBaseUrl.hostname)) { throw new ValidationError('Untrusted API host'); } this.baseUrl = parsedBaseUrl.origin; ``` Additional hardening measures: 1. Remove the fallback to Node.js's `http` module for authenticated requests. 2. Keep the endpoint fixed to `https://dev.voice.ai` unless custom endpoints are an explicitly required feature. 3. If custom endpoints are necessary, require an explicit opt-in and a caller-provided host allowlist. 4. Do not forward the `Authorization` header across redirects to a different origin. 5. Reject unsupported protocols, URL-embedded credentials, malformed hosts, and unexpected ports. 6. Add automated tests confirming that HTTP URLs and unapproved hosts are rejected before a request is sent. 7. Rotate the API key if it may already have been transmitted to an untrusted endpoint or over plaintext HTTP. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Credential Access

High
Category
Privilege Escalation
Content
export VOICE_AI_API_KEY="your-api-key-here"
```

**Method 2: .env File**
```bash
# Create .env file in project root
echo 'VOICE_AI_API_KEY=your-api-key-here' >> .env
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
**Method 2: .env File**
```bash
# Create .env file in project root
echo 'VOICE_AI_API_KEY=your-api-key-here' >> .env
```
Confidence
91% confidence
Finding
The instruction to append the API key directly into a local .env file encourages plaintext secret storage without any accompanying safeguards. If the project directory is shared, backed up insecurely, or accidentally committed, the API key can be exposed and used to manage or deploy voice agents.

Credential Access

High
Category
Privilege Escalation
Content
**Method 2: .env File**
```bash
# Create .env file in project root
echo 'VOICE_AI_API_KEY=your-api-key-here' >> .env
```

**Method 3: OpenClaw Config**
Confidence
89% confidence
Finding
The continued .env-based credential example reinforces insecure secret handling and normalizes storing long-lived API keys in plaintext within the project root. In the context of a skill that can create, deploy, and delete agents, compromise of that key enables unauthorized externally impactful actions.

Ae1

High
Category
analysis-evasion
Content
| `SKILL.md` | Documentation and OpenClaw skill definition |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill documentation describes access to environment variables and API-key based authentication, but it does not declare any explicit tool scope or permission boundaries. In an agent framework, undocumented capability to read env/config increases the risk of unintended secret exposure or over-privileged execution because the orchestrator and user are not clearly informed what the skill may access.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The feature list advertises destructive and externally impactful actions such as delete, deploy, and phone-number management without requiring explicit confirmation or warning guidance. In conversational systems, absence of confirmation for these operations can lead to accidental service changes, deletion of agents, or activation of outbound phone behavior from ambiguous user input.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Content
```

### Silent Initialization
The SDK automatically initializes when you run any command. No manual setup required after setting the API key.

## 🚀 Quick Start
Confidence
80% confidence
Finding
Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
"config": {
    "api_key": "${VOICE_AI_API_KEY}",
    "default_model": "gemini-2.5-flash-lite",
    "auto_deploy": false
  }
}
```
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The trigger phrases include broad natural-language terms like 'new agent', 'start the bot', and 'show agent' that may match ordinary conversation rather than an intentional request to use this skill. That can cause unintended activation of a skill capable of making external changes, which is especially risky because the skill supports deployment and deletion actions.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The CLI performs a destructive delete immediately once `delete --id` is invoked, with no confirmation prompt, `--force` gate, dry-run mode, or undo/recovery flow. In a command-line management tool for live voice agents, this increases the chance of accidental deletion from user error, scripting mistakes, or copied commands, causing service disruption and possible loss of configuration.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
/**
   * Delete (disable) an agent
   * Agent must be paused before being deleted.
   * Disabled agents are automatically deleted after a grace period.
   * @param {string} agentId - Agent ID
   * @returns {Promise<Object>} Deletion confirmation with agent details
   */
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The manifest describes a skill for creating, listing, deploying, and managing Voice.ai conversational agents and their configurations. This file also exposes separate resource-management capabilities for knowledge bases and phone numbers, which are materially broader product operations rather than obvious implementation details of basic agent management.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The deleteKnowledgeBase method performs a destructive DELETE request, but there is no confirmation prompt, user-facing log, or warning around this irreversible operation. In a code file, destructive operations should include some form of disclosure unless the warning is otherwise visibly provided.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The releasePhoneNumber method performs a potentially disruptive resource-release action, but the code provides no confirmation prompt, visible warning, or user-facing disclosure before sending the request. Releasing a phone number can affect service availability and should be explicitly surfaced to the user.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill advertises capabilities that can affect live external resources, including deploying voice agents, managing phone numbers, and integrating with MCP, but it does not warn users that these actions may trigger real-world changes or billing-impacting operations. In an agentic environment, missing safety disclosure increases the risk of unintended destructive or costly actions because users may not realize the skill can modify production systems.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
When creating an agent, the code sets language: args.language || 'en', which forces English as the default locale if the user does not explicitly choose one. This is a natural-language locale policy concern because the skill does not offer opt-in language selection before applying the default.

Description-Behavior Mismatch

Low
Confidence
85% confidence
Finding
The manifest focuses on creating, managing, and deploying voice agents, plus managing agent configurations. The analytics section adds reporting capabilities for call history, call details, and agent statistics, which are distinct read-oriented operations not mentioned in the stated skill purpose.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The file declares multiple supported languages, but the default TTS setting forces English by default. Under the language/locale policy, a fixed language preference can be a concern when not paired with explicit user choice or a documented justification.

Static analysis

No suspicious patterns detected.