Back to skill

Security audit

Umi

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches a clinic booking assistant, but it has review-worthy privacy and security gaps around automatic booking submission, shell-based browser opening, hard-coded API tokens, and an unverified APK download link.

Review before installing. This skill is not clearly malicious, but users should know that appointment details may be sent to BeautsGO immediately during the booking flow, and the package contains unsafe implementation choices. Prefer using official app stores over the direct APK link, and require the publisher to add explicit confirmation before data submission, remove hard-coded tokens, replace shell exec URL opening, constrain language-file loading, and align documentation with the UMI clinic.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T09 · Insecure Skill Coding Practices

Error
Location
api/browser/open-url.js:18
Finding

Shell Command Injection in the URL Opener

Content
View full analysis
hostname === host || hostname.endsWith('.' + host)) } catch { return false } } async function openUrl(url) { if (!url) throw new Error('URL is required') if (!isAllowedUrl(url)) throw new Error(`URL not allowed: ${url}`) if (process.platform === 'darwin') { await execAsync(`open "${url}"`) } else if (process.platform === 'win32') { await execAsync(`start "" "${url}"`) } else { await execAsync(`xdg-open "${url}"`) } } ``` ### Technical Analysis The URL is interpolated directly into a command passed to `child_process.exec`. The hostname allowlist only validates the parsed protocol and hostname; it does not make the complete URL safe for use in a shell command. Shell metacharacters and command substitutions can remain in URL components such as the path or query string. Double quotes do not prevent command substitution on Unix-like shells. Equivalent metacharacter behavior also creates risk on Windows. The function is exported and can additionally be invoked through the command-line interface using `process.argv[2]`. Any attacker who can control the URL passed to this function can potentially reach the vulnerable shell sink. ### Attack Path 1. The attacker constructs an HTTPS URL whose hostname passes the `i.beautsgo.com` allowlist. 2. The attacker places shell syntax in a URL path, fragment, or query component. 3. The URL passes `isAllowedUrl` because only its protocol and hostname are checked. 4. `openUrl` interpolates the original untrusted string into an `open`, `start`, or `xdg-open` shell command. 5. The operating-system shell interprets th ...[truncated 622 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
core/renderer.js:31
Finding

Path Traversal Through the Language Parameter

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
api/skill.js:21
Finding

Hard-Coded API Credentials in Distributed Source Code

Content
View full analysis
Remediation
View remediation

other

Warning
Location
api/skill.js:188
Finding

Personal Booking Data Is Transmitted Without the Declared Explicit Confirmation

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
api/skill.js:228
Finding

Direct Distribution of an Unverified Android APK

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description suggests a clinic-related informational or service skill about 明洞优美皮肤科 and cosmetic dermatology. The supplied code does not provide clinic content, booking, skin-care logic, or medical-aesthetics functionality. Instead, it performs a distinct system action: opening a whitelisted BeautsGO URL in the user's default browser via platform-specific shell commands. This is a materially different primary purpose and an undeclared capability, so the description does not accurately represent the code's behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

声明描述看起来像是一个关于“明洞优美皮肤科”的信息性技能,强调皮肤护理与医美项目;未声明任何权限或交互能力。实际代码则明显是一个预约与导流工具,具备多项主动能力:1)解析用户预约信息并提交到外部预约接口;2)调用价格查询接口;3)打开医院详情、价格表、在线客服网页;4)返回 APP 下载链接。这些都属于实质性功能,不只是支撑性实现细节。此外,代码头部注释写的是“JD皮肤科预约技能”,与声明中的“明洞优美皮肤科”存在对象不一致,说明描述与实际服务对象/用途也不完全匹配。因此应判定为描述与行为不符。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

声明描述强调的是某家皮肤科机构及其医美项目介绍,但代码并非单纯内容展示,而是面向预约场景的预处理逻辑。它会识别预约、咨询、价格、下载、打开页面等多种用户意图,并从自然语言中提取人数、日期、时间段和手机号等预约信息。这些属于实质性的功能能力,尤其是联系方式解析,未在声明中体现。此外,代码中的顶部注释与示例医院名称为“JD皮肤科”,与声明中的“明洞优美皮肤科”不一致,表明技能实际服务对象或主要用途存在偏差。因此应判定为描述与实际行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

声明描述的是特定医院“明洞优美皮肤科”的皮肤护理与医美项目,但代码并没有实现医院项目介绍或特定 UMI 机构逻辑,而是一个通用渲染器:读取本地多语言文件、把 hospital 数据填入预约模板、输出预约渠道相关 Markdown。虽然这可能是某个医院技能的组成部分,但就该代码块本身而言,其主要目的明显是“预约信息渲染”,且注释中还指向“JD皮肤科预约技能”,与声明中的“明洞优美皮肤科”不一致。因此应判定为描述与实际行为存在实质性不匹配。

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 4)May include surrounding context.

md
entry: api/skill.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
entry: api/skill.js

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation states that the skill collects user information and submits booking data to an external API, but it does not warn users that personal information may be transmitted off-platform. In a medical or cosmetic booking context, this can involve sensitive personal and contact data, increasing privacy and compliance risk if users are not given clear notice and consent.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script opens a URL by constructing shell commands and invoking them via child_process.exec, which introduces unnecessary command-execution capability into the skill. Although the URL is restricted to HTTPS and a specific host whitelist, launching the system browser is a privileged side effect not clearly required for a clinic-description/booking skill and could be abused for unwanted navigation, phishing on allowed subdomains, or future command-injection risk if validation changes.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The header comment says this is a "JD皮肤科预约技能" module, but the implementation loads a hospital record from ../data/hospital.json and is being shipped under the umi-booking skill for 明洞优美(UMI)皮肤科. This is not merely incomplete documentation: it actively identifies a different clinic/skill, which can mislead reviewers about the code's intended target and behavior.

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 · api/skill.js (reported line 21)May include surrounding context.

js
// ── 预约接口配置 ─────────────────────────────────────────────────────────────

const BOOKING_API_URL = 'https://api.yestokr.com/api/Appointment/saveFromSkill'
const BOOKING_API_TOKEN = 'beautsgo-openapi-fixed-token-change-me'

const PRICE_API_URL = 'https://apis.beise.com:50144/c5d1dcbc/ProjectDraft/search'

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 · skill.json (reported line 17)May include surrounding context.

json
// ── 预约接口配置 ─────────────────────────────────────────────────────────────

const BOOKING_API_URL = 'https://api.yestokr.com/api/Appointment/saveFromSkill'
const BOOKING_API_TOKEN = 'beautsgo-openapi-fixed-token-change-me'

const PRICE_API_URL = 'https://apis.beise.com:50144/c5d1dcbc/ProjectDraft/search'

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 · skill.json (reported line 30)May include surrounding context.

json
// ── 预约接口配置 ─────────────────────────────────────────────────────────────

const BOOKING_API_URL = 'https://api.yestokr.com/api/Appointment/saveFromSkill'
const BOOKING_API_TOKEN = 'beautsgo-openapi-fixed-token-change-me'

const PRICE_API_URL = 'https://apis.beise.com:50144/c5d1dcbc/ProjectDraft/search'

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

processQuery defaults lang to 'zh', and the skill responses throughout the file are written in Chinese. This imposes a specific language choice without offering the user a language or locale option in the skill logic shown here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The booking flow transmits user contact information and appointment details to an external API endpoint without a clear, prior disclosure or explicit consent step at the point of collection. This creates a privacy risk because users may provide phone numbers expecting in-chat assistance, not realizing their personal data will be forwarded to a third party platform.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The header comment describes this file as a "JD皮肤科预约技能" preprocessor, while the manifest states the skill is for 明洞优美(UMI)皮肤科. This is an active contradiction in documented intent, not just an omission, and suggests the file was copied from another clinic-specific skill without fully aligning its declared purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest says this skill is for 明洞优美(UMI)皮肤科, but the file header states 'JD皮肤科预约技能' and describes rendering hospital booking output for that clinic. This indicates the implemented/documented skill identity does not match the declared skill purpose, suggesting the code was copied from or intended for a different clinic flow.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The render function sets the default language to 'zh', and the file-level comments and labels are all Chinese-centric. Per the policy, forcing a specific language without user opt-in can be a natural-language locale violation unless the constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The string "Please tell me what you need — I'll help you" is a very broad invocation-style phrase that overlaps with ordinary conversation rather than a narrowly scoped booking trigger. In a manifest/localization file, this kind of wording can contribute to ambiguous activation or routing toward the booking skill without clear constraints.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The fallback text asks users to broadly state any need and promises help handling appointments, which can act as an overbroad trigger for unrelated user requests. In an agent setting, this increases the chance that arbitrary inputs are routed into this skill, causing unintended activation, scope confusion, or mishandling of requests outside the clinic-booking domain.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest description lists broad capabilities such as online consultation, price queries, and one-click booking, but it does not specify concrete trigger phrases, scope limits, or exclusion conditions. In a manifest file, this ambiguity can cause the skill to match common user requests about booking or consultation more broadly than intended.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The natural-language instructions and user-facing description are entirely in Chinese, while the policy requires avoiding a forced language or locale absent user opt-in. Although multilingual resource files are referenced, the documentation shown here does not tell users they can choose a language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file’s natural-language description and usage guidance are written in Chinese only, including the purpose and whitelist explanation. Under the stated policy, forcing a specific language without offering a language choice or documenting a justified locale constraint is a natural-language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file’s comments and documented input/output examples indicate the skill is designed around Chinese-language interaction only. Because there is no natural-language indication of user language choice or an explicitly documented region/language limitation, this can violate a language/locale policy requiring opt-in or justification.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The doc comment for project-keyword extraction uses the example "JD皮肤科 Onda 价格," which conflicts with the manifest naming this skill as UMI/优美皮肤科. While the function logic is generic, the inline documentation still indicates a different clinic context than the declared skill identity.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function defaults the lang parameter to zh, which imposes a specific language choice when the caller does not explicitly provide one. This can violate language/locale policy if users are not given a choice or informed of the default behavior.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
api/skill.js:25