Back to skill

Security audit

Claw Body

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent avatar and presentation purpose, but its local server exposes sensitive unauthenticated APIs and unsafe command execution paths that need review before installation.

Only install this after reviewing the local-server risks. While running, another webpage or local process could potentially call its APIs, obtain NuwaAI tokens, alter stored configuration, send prompts through your OpenClaw gateway, or exploit the presentation parsing path. Use a test account/key, avoid confidential slide decks, and stop the server when finished.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
server.mjs:141
Finding

Unauthenticated Cross-Origin Access to Privileged Local APIs

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
server.mjs:420
Finding

OS Command Injection Through Presentation Paths and Uploaded Filenames

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
server.mjs:46
Finding

NuwaAI API Key Stored in Plaintext With Default File Permissions

Content
View full analysis
Remediation
View remediation

other

Warning
Location
public/index.html:996
Finding

Microphone Capture and Third-Party Audio Transmission Start Automatically

Content
View full analysis
{ console.log( "[NuwaAI] WebSocket connected, starting audio capture (asr mode)" ); if (!isRecording) { startRec(); } }; ``` The recording function requests microphone access and transmits PCM data to NuwaAI: ```js mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true }); audioContext = new ( window.AudioContext || window.webkitAudioContext )({ sampleRate: 16000, channelCount: 1 }); await audioContext.audioWorklet.addModule("/pcm-processor.js"); const source = audioContext.createMediaStreamSource(mediaStream); workletNode = new AudioWorkletNode(audioContext, "pcm-processor"); workletNode.port.onmessage = (event) => { if (event.data.type === "audioData") { if ( isRecording && wsNuwa?.readyState === WebSocket.OPEN ) { wsNuwa.send(event.data.data); } } }; source.connect(workletNode); workletNode.connect(audioContext.destination); isRecording = true; ``` ### Technical Analysis Voice transmission to NuwaAI is consistent with the declared ASR feature. However, automatically calling `startRec()` on WebSocket connection is broader than the minimum permission needed. The browser prompts the user on first microphone access, but permission may already have been granted. On later connections or reconnections, audio collection can begin immediately without a new, explicit recording action. The application then continuously transmits microphone samples to the third-party Nuw ...[truncated 936 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
public/index.html:983
Finding

NuwaAI Access Token Exposed in WebSocket Query String

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
Findings (23)

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · public/index.html (reported line 513)May include surrounding context.

html
</head>
<body>

<!-- ─── Welcome Screen ─── -->
<div id="welcome-screen">
  <div class="welcome-card">
    <div style="text-align:right;margin-bottom:8px;">

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · public/index.html (reported line 565)May include surrounding context.

html
</div>
</div>

<!-- ─── Trial Expired Overlay ─── -->
<div id="trial-overlay">
  <div class="trial-card">
    <div class="icon">⏰</div>

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · public/index.html (reported line 565)May include surrounding context.

html
</div>
</div>

<!-- ─── Trial Expired Overlay ─── -->
<div id="trial-overlay">
  <div class="trial-card">
    <div class="icon">⏰</div>

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

When the WebSocket connects, the code automatically calls startRec() and begins microphone capture if permission has already been granted. This creates a covert audio-capture risk because reconnects or initial connection can activate recording without a fresh, explicit user action or a clear just-in-time disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

Captured microphone PCM chunks are sent directly over the WebSocket to a remote NuwaAI service, but the UI does not clearly disclose at the point of recording that live speech is being transmitted off-device. In a voice/avatar skill, this is particularly sensitive because users may assume audio is only local or only used after explicit send actions.

Content

No source excerpt is available for this finding.

Unvalidated Output Injection

High
Category
Output Handling
Confidence
90% confidence
Finding

Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.

Content

Scanner excerpt · server.mjs (reported line 119)May include surrounding context.

js
// Parse [PAGE:N] blocks
  const pageRegex = /\[PAGE:(\d+)\]([\s\S]*?)(?=\[PAGE:\d+\]|$)/g;
  let match;
  while ((match = pageRegex.exec(reply)) !== null) {
    const pageNum = parseInt(match[1], 10);
    const script = match[2].trim();
    const slide = data.slides.find(s => s.page === pageNum);

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The server exposes an unauthenticated endpoint that mints and returns NuwaAI access tokens derived from a hard-coded demo API key. Combined with permissive CORS and local HTTP service exposure, any local webpage or process able to reach the port can harvest usable third-party tokens and abuse the demo account or consume its quota.

Content

Scanner excerpt · server.mjs (reported line 212)May include surrounding context.

js
return;
    }

    // /api/demo/token — get access token
    if (url.pathname === "/api/demo/token") {
      try {
        const resp = await fetch("https://api.nuwaai.com/web/apiKey/auth", {

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The /api/token endpoint returns a live NuwaAI access token for the user's configured API key to any caller, with no authentication or authorization checks. Any local website, browser extension, or process that can reach this service can extract the token and impersonate the user against NuwaAI services.

Content

Scanner excerpt · server.mjs (reported line 231)May include surrounding context.

js
}
  }

  // API: Get NuwaAI access token
  if (req.url === "/api/token" && req.method === "GET") {
    if (!nuwaConfig.apiKey) {
      res.writeHead(200, { "Content-Type": "application/json" });

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to read a local presentation file, generate content, and then update presentation.json on disk without explicitly warning the user that local files will be modified or requiring confirmation before the write. This creates a real risk of unintended data modification, especially because the workflow targets user-supplied file paths and silently alters presentation artifacts as part of normal operation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code contains strings for microphone permission, recording state, and connection to an avatar service, indicating the skill captures live audio. However, there is no explicit warning in this file telling users that their voice may be sent to a remote service or processed externally; the text only reports permission/errors after the fact.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The setup flow sends the entered API key, avatar ID, and user ID to /api/config, but the surrounding UI only asks for the values and does not warn users that these credentials and identifiers will be transmitted to a backend service. For a safety-sensitive credential handling operation, there is no visible disclosure near the submission action.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file includes multiple Chinese-only user-facing messages and, more importantly, the narration-generation prompt explicitly requires Chinese output. Because the skill does not offer user opt-in or a locale choice for these behaviors, it appears to enforce a specific language in violation of the language/locale policy.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

Presentation contents are bundled into a prompt and transmitted to the OpenClaw gateway for script generation without explicit consent or warning. Because slides may contain confidential business or personal data, silent transmission to another service materially increases data exposure risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

User-supplied NuwaAI credentials are persisted in plaintext to .nuwa-config.json without any access controls, encryption, or user warning. On a shared system or if local files are exposed through backups, malware, or other local compromise, these credentials can be recovered and abused.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · server.mjs (reported line 215)May include surrounding context.

js
// /api/demo/token — get access token
    if (url.pathname === "/api/demo/token") {
      try {
        const resp = await fetch("https://api.nuwaai.com/web/apiKey/auth", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ secretKey: demo.apiKey }),

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · server.mjs (reported line 239)May include surrounding context.

js
// /api/demo/token — get access token
    if (url.pathname === "/api/demo/token") {
      try {
        const resp = await fetch("https://api.nuwaai.com/web/apiKey/auth", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ secretKey: demo.apiKey }),

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · server.mjs (reported line 215)May include surrounding context.

js
// /api/demo/token — get access token
    if (url.pathname === "/api/demo/token") {
      try {
        const resp = await fetch("https://api.nuwaai.com/web/apiKey/auth", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ secretKey: demo.apiKey }),

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · server.mjs (reported line 239)May include surrounding context.

js
// /api/demo/token — get access token
    if (url.pathname === "/api/demo/token") {
      try {
        const resp = await fetch("https://api.nuwaai.com/web/apiKey/auth", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ secretKey: demo.apiKey }),

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest frames the skill as an avatar/voice/presentation experience, yet the code exposes /api/chat and /api/chat/stream that forward arbitrary user messages to the OpenClaw chat completions endpoint. That is broader than slide narration or avatar control and effectively adds a generic chat gateway behavior not described in the manifest.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The upload endpoint writes the uploaded file to a temp path and invokes parse-presentation.py through execSync. While these actions may be functionally expected, the code lacks any confirmation, visible notice, or explanatory warning that uploaded content is being written locally and handed to an external parser process.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes a skill for giving Claw a real-time avatar with voice/expressions and presenting slides, but it does not indicate that the server will invoke local subprocesses. The upload and parse flows call a Python script via child_process.execSync to process user-supplied presentation files, which is a materially broader capability than the stated avatar/presentation interface.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The language detection logic automatically selects Chinese for any zh-prefixed browser locale and English otherwise. This imposes a locale decision without explicit user choice, which matches the language/locale policy concern for natural-language behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code packages captured microphone PCM samples and posts them out of the AudioWorklet via MessagePort. There is no confirmation prompt, user-facing notice, or explanatory comment in this file indicating that raw audio data is being forwarded, which can affect privacy-sensitive user data handling.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.exposed_secret_literal

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
server.mjs:119

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
server.mjs:8

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
public/index.html:817

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
server.mjs:34