Back to skill

Security audit

AI 书稿图片重设计

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent static AI image-redesign web app, but it handles API keys and external API responses in ways that could expose credentials or uploaded content.

Review this skill before installing or deploying. Use only test or low-privilege API keys, avoid unpublished or sensitive manuscript images unless you trust the configured API endpoint, and prefer a backend proxy that keeps credentials server-side. The static page should be hardened before real use by removing localStorage key persistence, enforcing HTTPS and same-origin polling, validating result URLs, and rendering API messages as text rather than HTML.

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

T09 · Insecure Skill Coding Practices

Error
Location
assets/index.html:254
Finding

Persistent Plaintext Storage of API Credentials

Content
View full analysis
localStorage.setItem(API_BASE_STORAGE_KEY, apiBaseInput.value.trim())); apiKeyInput.addEventListener('change', () => localStorage.setItem(API_KEY_STORAGE_KEY, apiKeyInput.value.trim())); ``` ### Technical Analysis The application persists the user's bearer API key in `localStorage`. Local storage provides no confidentiality protection and is readable by any JavaScript executing under the same origin. The credential also remains available after the page is closed and across browser sessions. The password input type only masks the displayed characters; it does not protect the value after storage. This weakness becomes particularly serious in combination with the DOM injection vulnerabilities elsewhere in the page, because injected JavaScript can directly retrieve the key using: ```javascript localStorage.getItem('book_redesign_api_key') ``` The credential may also be exposed to compromised same-origin pages, malicious browser extensions with page access, or anyone with access to the browser profile. ### Attack Path 1. A user enters a valid API key in the API settings form. 2. The input's `change` handler writes the plaintext key to `localStorage`. 3. Malicious JavaScript gains execution under the page's origin, such as through one of the API-response DOM injection vulnerabilities. 4. The malicious code reads `book_redesign_api_ke ...[truncated 556 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
assets/index.html:354
Finding

DOM-Based Cross-Site Scripting Through API Error Messages

Content
View full analysis
i.id === selectedId); const el = document.getElementById('detailCard'); if (!img) { el.style.display = 'none'; return; } el.style.display = ''; const right = img.resultUrl ? `` : `
${img.status === 'error' ? `处理失败:${img.error || '未知错误'}` : img.status === 'processing' ? `正在处理中${img.taskId ? `\n任务ID:${img.taskId}` : ''}` : '填写 URL、API Key、模型名后,上传图片即可直接使用。支持同步返回与异步轮询。'}
`; el.innerHTML = `
🖼️ 当前图片
原图
生成结果
${right}
`; } ``` API-derived exception text is assigned to `current.error` and subsequently rendered: ```javascript try { await processOneImage(current, i, images.length); success += 1; } catch (err) { current.status = 'error'; current.error = err.message || '请求失败'; addLog(`第 ${i+1}/${images.length} 张失败:${current.error}`); } renderThumbs(); renderActions(); renderDetail(); ``` The exceptions can contain API-controlled messages, for example: ```javascript if (!res.ok) throw new Error(data?.error?.message || data?.message || `请求失败(${res.status})`); ``` ### Technical Analysis Error messages returned by the configured API are treated as trusted HTML. The error is placed in `current.error`, interpolated into the `right` HTML fragment, and assigned to `el.innerHTML` without contextual encoding or sanitization. A malicious endpoint can return an error message containing active HTML, such as an image element with an `onerror` handler. Whe ...[truncated 1681 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
assets/index.html:307
Finding

DOM Injection Through Unvalidated API Result URLs

Content
View full analysis
i.status === 'done' && i.resultUrl); const firstDone = images.find(i => i.status==='done' && i.resultUrl); el.innerHTML = `🚀 开始处理 (${images.length}张)清空${hasDone ? `💾 下载首张结果` : ''}`; } function renderDetail(){ const img = images.find(i => i.id === selectedId); const el = document.getElementById('detailCard'); if (!img) { el.style.display = 'none'; return; } el.style.display = ''; const right = img.resultUrl ? `` : `
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
assets/index.html:366
Finding

Bearer Credential Disclosure to Arbitrary Polling Origins and Plaintext HTTP Endpoints

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

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.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 35)May include surrounding context.

md
- `assets/index.html`:可直接打开的静态页面模板

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 76)May include surrounding context.

md
- `assets/index.html`:可直接打开的静态页面模板

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The markdown explicitly says to use the skill when users say phrases like '做一个静态网页工具 skill' or '把前端 demo 打包成可复用 skill', which are broad requests that could match many unrelated web-to-skill tasks. The file does not provide exclusion conditions or negative examples to distinguish this skill from other HTML/frontend conversion skills.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs users to enter API Base URL and API Key directly into a browser-based static page, which can expose secrets to client-side JavaScript, browser storage, shared machines, extensions, and accidental screenshots or screen recordings. Although the document briefly recommends server-side alternatives later, the warning is not prominent enough up front relative to the risky workflow being encouraged.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This skill sends user images and prompts to an arbitrary user-specified external API, but the interface does not present a prominent warning at the point of upload or processing that sensitive content will be transmitted off-device. In this skill context, uploaded book-manuscript graphics may contain unpublished or proprietary material, so lack of disclosure increases the risk of accidental data exfiltration to untrusted endpoints.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Manifest 描述强调的是把现成 HTML/前端原型落地为本地可复用网页应用,并提到最终用户可自行填写 API URL 和 API Key。该文件除了提供可配置输入外,还直接把上传图片转为 data URL、向远程 /v1/images/generations 发起请求并轮询任务结果,实际实现了一个联网的 AI 图像重设计客户端,而不只是静态页面封装。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The API key is stored in localStorage, which is accessible to any script running in the page origin and persists beyond the current session. If the page origin is later exposed to XSS, malicious third-party scripts, or shared-browser access, the stored credential can be recovered and used to make unauthorized API calls or access paid services.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The document declares lang="zh-CN", and the entire interface text is presented only in Chinese, which effectively fixes the skill to a single language. Under the stated policy, a forced language/locale without user opt-in or documented justification should be flagged.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

该 skill 的声明用途是把图片重设计工具做成可复用网页应用,并支持用户填写 API 配置。代码额外实现了免费次数统计、额度耗尽展示和升级提示,这属于商业化/变现控制逻辑,而不是完成页面封装或图片重设计所必需的能力。

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.