T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/google-voice-mcp.js:112- Finding
Unrestricted Raw API Tool Can Perform Unauthorized Google Voice Operations
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Google Voice skill is mostly coherent, but it grants broad authenticated account actions without strong built-in guardrails.
Review before installing. Use this only with a Google Voice account you are comfortable automating, keep it away from shared workspaces, prefer browser/CDP mode over cookie exports, avoid gv_raw_call unless you understand the exact endpoint, and do not run audio mode as a privileged user. Treat exported SMS records, HAR samples, generated speech, and call recordings as sensitive private data.
scripts/google-voice-mcp.js:112Unrestricted Raw API Tool Can Perform Unauthorized Google Voice Operations
scripts/google-voice-mcp.js:111External SMS and Call Actions Lack an Enforced Approval Boundary
scripts/google-voice-call-audio-engine.js:9Google Session Cookies Are Loaded into an Unsandboxed Chromium Process
scripts/google-voice-call-audio-engine.js:8Sensitive Messages and Call Audio Use Predictable or Insufficiently Protected Files
scripts/analyze_voice_har.py:13HAR Analyzer Uses Incomplete Heuristic Redaction Before Printing Request Bodies
scripts/google-voice-call-audio.sh:31Call Text Is Transmitted to an External TTS Provider Without Explicit Disclosure
The skill description does not accurately bound what the implementation can do, while the documented toolset includes a raw endpoint invocation capability (gv_raw_call) and OAuth token refresh behavior that materially expand its power. In a telecom/messaging context, this mismatch is dangerous because operators or agents may rely on the description and overlook that the skill can make arbitrary Google Voice requests or handle additional credentials beyond the declared use cases.
Referenced artifact was not completely inspected
Prefer the CDP `google-voice-start-call.js` mode for simple manual/live calls because it reuses the logged-in visible browser and avoids cookie exports. Use aud
Referenced artifact was not completely inspected
Prefer the CDP `google-voice-start-call.js` mode for simple manual/live calls because it reuses the logged-in visible browser and avoids cookie exports. Use aud
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.
AUDIO_PATH="$FINAL_WAV"
fi
if [[ "$DRY_RUN" == "1" ]]; then printf '{"dryRun":true,"number":"%s","authuser":"%s","audioPath":"%s","duration":%s}\n' "$NUMBER" "$AUTHUSER" "$AUDIO_PATH" "$DURATION"; exit 0; fi
RECORDING_WEB="/tmp/gv_recorded_incoming.webm"; RECORDING_MP3="/tmp/gv_call_$(date +%Y%m%d_%H%M%S).mp3"; rm -f "$RECORDING_WEB"
node "$SKILL_DIR/scripts/google-voice-call-audio-engine.js" "$NUMBER" "$AUDIO_PATH" "$DURATION" "$AUTHUSER"
if [[ -f "$RECORDING_WEB" ]]; then ffmpeg -i "$RECORDING_WEB" -q:a 0 -map a "$RECORDING_MP3" -y >/dev/null 2>&1 || true; echo "FINISHED_FILE:$RECORDING_MP3"; fi
The skill exposes sensitive capabilities involving environment variables, file access, and networked interaction with Google Voice, but it does not declare any explicit tool scope or permissions boundaries. In a high-risk skill that handles HAR-derived credentials, cookies, SMS content, and outbound communications, missing scope declarations increases the chance of unintended tool access or unsafe execution by an agent runtime.
This Python script reads a Google Voice HAR file, extracts request payloads, and prints sample request data after only partial redaction. Although some fields are masked, the code has no confirmation prompt, warning comment, or user-facing disclosure that it processes potentially sensitive communications and metadata from the HAR file.
This script silently captures call audio via MediaRecorder and writes it to a predictable file path on disk without any runtime notice, consent enforcement, or jurisdictional compliance checks. In the context of a Google Voice automation skill that can place outbound calls and inject audio, this creates a meaningful risk of covert call recording, unauthorized retention of sensitive communications, and legal/privacy violations.
The manifest describes using HAR captures, browser sessions, and bundled MCP integration for Google Voice web automation. In gws mode, the code shells out to a separate gws binary, reads exported OAuth refresh credentials, and exchanges them for access tokens, introducing a distinct credential-handling capability not called out in the stated skill purpose.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
refresh_token: creds.refresh_token,
grant_type: 'refresh_token',
});
const res = await fetch('https://oauth2.googleapis.com/token', { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: params });
const j = await res.json();
if (!res.ok || !j.access_token) throw new Error('gws token refresh failed: ' + JSON.stringify({ error: j.error, error_description: j.error_description }));
GWS_TOKEN_CACHE = { token: j.access_token, exp: now + (j.expires_in || 3000) };
The exposed tool set consists of gv_list_threads, gv_get_thread, gv_send_sms, and gv_raw_call. There are no tools or code paths for starting calls, injecting audio/TTS, recording call audio, exporting records, or configuring OpenClaw integration, so the actual behavior of this file is materially narrower than the manifest description claims.
The gv_list_threads and gv_get_thread tools fetch Google Voice thread metadata and message contents using browser cookies, authorization headers, or refreshed OAuth access tokens. While their descriptions say authentication is required, the code provides no explicit runtime disclosure or warning that private communications will be accessed and returned to the caller.
The gv_raw_call tool allows arbitrary authenticated calls to Google Voice endpoints using the user's browser session, cookies, or OAuth-derived bearer token. This bypasses the narrower user-facing purpose of the skill and creates a confused-deputy risk where an agent or prompt can invoke undocumented or sensitive operations against the account.
A generic raw-call tool with authenticated Google Voice access materially expands the attack surface beyond the described SMS/thread features. In an agent setting, this makes prompt injection or tool misuse more dangerous because arbitrary backend actions can be performed under the user's authority without meaningful guardrails.
The script can export Google Voice SMS thread contents to an arbitrary file path via --out with no interactive warning, consent checkpoint, or data-classification notice. Because this skill is explicitly designed to access and export sensitive communications, silent persistence to disk materially increases the risk of unauthorized retention, later exfiltration, or accidental disclosure through logs, backups, or shared workspaces.
The comment suggests a narrowly non-credential-handling design, yet getGwsAccessToken actively retrieves credential material from gws auth export and uses it to mint bearer tokens. Even if credentials are not persisted to disk here, the documentation downplays the code's actual interaction with sensitive auth secrets.