Back to skill

Security audit

德牧洒洒·房车陪伴助手

Security checks for vulnerabilities and agentic risk

Overview

This skill is a static voice-assistant demo that falsely presents navigation, email, meeting, search, and camera actions as completed, so users could rely on results that never happened.

Install only if you understand this as a local prototype, not a working RV assistant. Do not rely on it for driving, traffic, fuel, email, meetings, search, or camera actions unless the skill is changed to clearly label simulations and to verify real integrations. Avoid entering sensitive text because the page has unsafe HTML rendering and browser speech recognition may process audio through browser or vendor services.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
assets/index.html:408
Finding
DOM-Based Cross-Site Scripting Through Chat Input<![CDATA[ ## Vulnerability Details **File Location**: `assets/index.html`, lines 408-424 **Vulnerability Type**: DOM-based cross-site scripting **Risk Level**: Medium ### Vulnerable Code ```javascript function appendMsg(text, role) { const box = document.getElementById("chatBox"); const div = document.createElement("div"); div.className = `msg ${role}`; if (role === "sasa") { div.innerHTML = ` <img src="sasa_avatar.png" class="msg-avatar" alt="Assistant"> <div class="bubble">${text.replace(/\n/g, "<br>")}</div>`; } else { div.innerHTML = ` <div class="msg-avatar user-avatar">👤</div> <div class="bubble">${text}</div>`; } box.appendChild(div); box.scrollTop = box.scrollHeight; } ``` ### Technical Analysis The `appendMsg` function inserts the `text` parameter into an HTML template and assigns the result to `innerHTML`. No HTML escaping, sanitization, or element allowlisting is performed before this assignment. The value originates from the text input or the browser speech-recognition transcript. An attacker-controlled string containing HTML with event handlers can therefore create executable DOM nodes. For example, the following input can execute JavaScript when the browser attempts to load the invalid image: ```html <img src="invalid" onerror="alert(document.domain)"> ``` Assistant responses are also rendered through `innerHTML`. Several responses incorporate portions of the user's input, such as a navigation destination or search query. Consequently, removing only the vulnerable user-message branch would not fully address the problem. This is DOM-based XSS because the injection and execution occur entirely in client-side JavaScript without requiring a server response. ### Attack Path 1. A user opens `assets/index.html` in a browser. 2. An attacker causes malicious HTML to be entered into the chat field. This could occur through direct input, pasted content, or a transcript produced after the user acti ...[truncated 1310 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `innerHTML` with DOM construction and `textContent` for every user-controlled value: ```javascript function appendMsg(text, role) { const box = document.getElementById("chatBox"); const message = document.createElement("div"); message.className = `msg ${role}`; if (role === "sasa") { const avatar = document.createElement("img"); avatar.src = "sasa_avatar.png"; avatar.className = "msg-avatar"; avatar.alt = "Assistant"; const bubble = document.createElement("div"); bubble.className = "bubble"; bubble.textContent = text; message.append(avatar, bubble); } else { const avatar = document.createElement("div"); avatar.className = "msg-avatar user-avatar"; avatar.textContent = "👤"; const bubble = document.createElement("div"); bubble.className = "bubble"; bubble.textContent = text; message.append(avatar, bubble); } box.appendChild(message); box.scrollTop = box.scrollHeight; } ``` 2. Preserve line breaks through CSS rather than converting them to HTML: ```css .bubble { white-space: pre-wrap; } ``` 3. If rich-text output is genuinely required, sanitize it with a maintained allowlist-based sanitizer such as DOMPurify. Disable event attributes, script-capable URL schemes, embedded frames, and active SVG or MathML content. 4. Apply a restrictive Content Security Policy as defense in depth. Avoid allowing inline scripts and inline event handlers. 5. Add regression tests covering HTML elements, event-handler attributes, encoded payloads, malformed markup, SVG payloads, and user-controlled values reflected through assistant responses. ]]>

T07 · Tool Hijacking and Spoofing

Error
Location
assets/index.html:363
Finding
Fabricated Results for Navigation, Email, Meeting, Search, and Camera Operations<![CDATA[ ## Vulnerability Details **File Location**: `assets/index.html`, lines 363-390 **Vulnerability Type**: Capability and tool-result spoofing **Risk Level**: High ### Vulnerable Code The response table returns fixed success messages rather than invoking or validating the represented services: ```javascript const responses = { "navigation": (msg) => { const dest = msg.replace(/.*navigate to|.*go to/, "").trim() || "destination"; return `Acknowledged. Planning a route to "${dest}".\n\nNavigation has started.\nThe optimal route has been prepared.`; }, "traffic": () => `Checking live traffic.\n\nThe main roads are clear. Ask for an alternative route if necessary.`, "fuel station": () => `Searching for nearby fuel stations.\n\nThree fuel stations were found at 1.2 km, 2.8 km, and 4.1 km.`, "email": () => `Checking the mailbox.\n\nThere are two unread messages from a manager and a meeting notification.`, "meeting": (msg) => { const meetId = msg.match(/\d{6,}/)?.[0]; return meetId ? `Opening the meeting application and joining meeting ${meetId}.` : `Opening the meeting application. Provide a meeting number to join.`; }, "camera": () => `Opening the camera. Say "take a photo" when ready.`, "take photo": () => `The photo was captured and saved to the album.`, "search": (msg) => { const query = msg.replace(/.*search/, "").trim(); return `Searching for "${query}".`; } }; ``` The snippet above is an English rendering of the response logic at the cited location. The source implementation uses localized command keys and messages but has the same behavior: it only returns strings. ### Technical Analysis The Skill documentation represents the application as capable of controlling navigation, reading and replying to email, opening or joining meetings, performing searches, and controlling a camera. However, the reviewed project contains only one static HTML file and no implementation for ...[truncated 2691 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Clearly label the current application as a demonstration or non-functional prototype. Every simulated result should state that no real service was contacted and no action occurred. 2. Remove claims of successful execution until the corresponding action has been confirmed by a real integration. 3. Implement each capability through an appropriate supported API: - Use a navigation deep link or documented navigation SDK and verify successful handoff. - Retrieve traffic and nearby-place data from an authenticated provider using current location and timestamped results. - Use an authorized email API with explicit account consent and least-privilege scopes. - Use documented meeting deep links or APIs and report whether the handoff succeeded. - Use `getUserMedia()` or another supported camera API only after explicit permission. - Save photographs only after capture succeeds, and display storage errors. - Open searches through explicit, visible URLs or a documented search integration. 4. Separate statuses into states such as `requested`, `permission required`, `in progress`, `completed`, and `failed`. Display success only after receiving verifiable confirmation. 5. Require user confirmation before sensitive or consequential operations, including sending email, joining a meeting, changing navigation, or capturing media. 6. Display the data source and freshness for navigation, traffic, nearby-place, and email results. 7. Handle denied permissions, unavailable APIs, offline conditions, malformed meeting identifiers, and third-party service failures without falling back to fabricated success. 8. Update `SKILL.md` so that documented capabilities exactly match the implemented behavior. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Hidden Instructions

High
Category
Prompt Injection
Content
<div class="chat-container">
  <div class="chat-box" id="chatBox">
    <!-- 初始欢迎消息 -->
    <div class="msg sasa">
      <img src="sasa_avatar.png" class="msg-avatar" alt="洒洒">
      <div class="bubble">
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
<div class="chat-container">
  <div class="chat-box" id="chatBox">
    <!-- 初始欢迎消息 -->
    <div class="msg sasa">
      <img src="sasa_avatar.png" class="msg-avatar" alt="洒洒">
      <div class="bubble">
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill advertises sensitive capabilities including email reply, web search, camera control, and common app control without any user-facing warning, consent language, or safety boundaries. In this context, users may not understand that invoking the assistant could expose private data or trigger real-world actions, increasing the risk of privacy violations and unintended operations.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The activation keywords are broad and include common terms like “导航”, “高德”, and “腾讯会议”, which can cause unintended invocation during normal conversation. Because the skill can control navigation, email, search, meetings, camera, and apps, accidental activation could lead to unauthorized or unexpected sensitive actions, especially in a voice-driven environment.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The page declares a fixed Chinese locale and the speech recognition logic is later hard-coded to zh-CN, which indicates the skill is designed to operate in a specific language without any opt-in or alternative. The policy allows locale constraints only when they are user-selectable or clearly justified as region-specific.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The manifest describes a voice-controlled RV assistant that can operate Gaode navigation, reply to email, perform Baidu/Google searches, launch Tencent Meeting, and control common apps. In this code, those capabilities are represented only as hardcoded text templates in the responses object, with no integration to navigation, mail, meeting, search, or app APIs, so the implemented behavior is materially narrower than advertised.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The page activates browser speech recognition and forwards microphone audio to the browser's speech-recognition subsystem without any in-app privacy disclosure about how audio may be processed or transmitted. In a voice assistant context, users may reveal sensitive location, contact, travel, or message content, so lack of clear notice and consent increases privacy risk.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The speech recognition engine is explicitly configured to use zh-CN only, and the interface provides no language choice or consent flow. This is a natural-language policy issue because it imposes a language/locale constraint on all users without opt-in.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
The inline welcome message actively tells users to say the wake phrase to wake the assistant, implying passive wake-word behavior. However, the only voice logic is in toggleVoice(), which requires a button click to start browser speech recognition and contains no logic to detect or react specially to the wake phrase.

Static analysis

No suspicious patterns detected.