Back to skill

Security audit

Jd

Security checks for vulnerabilities and agentic risk

Overview

This clinic booking skill mostly matches its purpose, but it needs review because it sends appointment data, embeds API tokens, opens URLs through a shell, and promotes an unverified APK download.

Review before installing. Use only if you are comfortable with appointment details and an optional phone number being sent to BeautsGO/yestokr services, and avoid the direct APK link unless the publisher provides a trusted checksum or store-based installation path. The publisher should rotate exposed API tokens, replace shell URL opening with argument-based process launch, and add an explicit booking confirmation step.

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

T09 · Insecure Skill Coding Practices

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

OS Command Injection Through Shell-Based URL Opening

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 function validates the URL by parsing its protocol and hostname, but it subsequently interpolates the original, unnormalized input into an operating-system shell command executed through `child_process.exec`. Hostname validation does not ensure that the original string is safe for shell interpolation. An input may parse as an HTTPS URL under an allowed hostname while also containing quote characters or shell metacharacters in another URL component. Those characters can terminate the quoted command argument and introduce additional shell commands. The vulnerable function is exported and can also be invoked through the documented command-line interface. The current `processQuery` paths supply URLs from static hospital data, which limits exposure through that particular caller, but direct callers and the CLI can supply arbitrary input. ### Attack Path 1. An attacker obtains access to a code path that calls the exported `openUrl` function, or can invoke `node api/browser/open-url.js`. 2. The attacker provides a crafted HTTPS URL whose parsed hostname is `i.beautsgo.com` or a permitted subdomain. 3. The crafted URL includes quote charac ...[truncated 688 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
api/skill.js:21
Finding

Hardcoded Booking and Pricing API Credentials

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
api/skill.js:164
Finding

Personal Data Is Transmitted Without an Explicit Confirmation Gate

Content
View full analysis
信息不全也没关系,分多次告诉我也可以 😊` } if (!hospital.id) { return `❌ 该医院暂不支持在线预约,请手动预约:${hospital.url || ''}` } const dateISO = parseDateToISO(formData.dateText) const expectedTime = formData.timeSlot && formData.timeSlot !== '全天' ? `${dateISO} ${formData.timeSlot}` : `${dateISO} 全天` const payload = { contact: formData.contact || '', expected_time: expectedTime, project_type: '', d_id: '', h_id: hospital.id, p_id: '', num: formData.persons, source_type: 'skill', } const result = await submitBookingApi(payload) ``` ### Technical Analysis The booking branch submits data immediately whenever a date is successfully parsed. If the same message includes a phone number, that number is placed in `payload.contact` and transmitted to the external booking service. There is no intermediate review screen, explicit disclosure of the receiving endpoint, affirmative confirmation check, or consent state before the POST request. This conflicts with the package privacy declaration that the phone number is sent only after explicit user consent. The absence of a confirmation gate also increases the chance of unintended submissions caused by intent-detection or natural-language parsing errors. ### Attack Path 1. A user enters a booking request containing a date and phone number. 2. `parseFormInput` extracts the date, phone number, time slot, and party size. 3. Because `dateText` is present, the function skips the information-request response. 4. ...[truncated 664 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
api/skill.js:228
Finding

Unverified Direct APK Distribution From an Undeclared Host

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents the skill as informational or service-related content about a dermatology clinic. However, the supplied code does not provide clinic information, booking logic, treatment details, or any dermatology-specific behavior. Instead, it performs a distinct technical action: validating and opening a whitelisted BeautsGO URL in the user's browser. 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

The declared description presents the skill as a basic clinic description/profile, but the code performs operational actions: booking appointments, querying prices, opening external URLs, connecting to customer-service pages, and distributing app download links. These are material capabilities not reflected in the declared purpose. No permissions are declared, yet the code makes outbound network requests and opens URLs. This is a meaningful description-behavior mismatch rather than mere implementation detail.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents the skill as a clinic profile/information skill about JD皮肤科, but the supplied code is clearly for an appointment-related transactional skill. It supports booking flow continuation, consultation, price lookup, opening links/pages, and even download/app intents. It also parses structured reservation data including phone numbers, which is a materially different and more operational capability than a simple clinic description. No permissions are declared, yet the code is designed to handle user contact information and booking details. This is a meaningful description-behavior mismatch, not merely an implementation detail.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description presents the skill as a clinic identity/profile for JD皮肤科. However, the supplied code explicitly identifies itself as 'JD皮肤科预约技能 — 渲染层' and builds a booking guide template with channels such as iOS, Android, WeChat mini program, official account, and web. Its primary function is rendering appointment-related Markdown from hospital data and i18n content, not merely describing the clinic. It also accesses local i18n JSON files via fs/path, which is an operational resource usage absent from the declared permissions. This is a material description-versus-behavior mismatch.

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

md
entry: api/skill.js

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 18)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 31)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
84% confidence
Finding

The main entry point sets lang = 'zh' by default, and the surrounding user-facing strings are all Chinese, which effectively forces a locale unless another component overrides it. There is no visible prompt offering a language choice or documenting a justified region-specific language restriction in this file.

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 personal data, including contact information and appointment details, to an external booking API without an explicit notice or consent step at submission time. In a medical/clinic context, even limited scheduling data can be privacy-sensitive, so silent transmission increases compliance and user-trust risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file’s natural-language comments and documented examples are entirely Chinese and describe the skill specifically as a JD dermatology appointment skill, with no indication that users may choose another language or locale. Under the policy rule for language/locale, this is a documented constraint without explicit opt-in or user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The render function sets the default language to 'zh', which forces a specific locale when no user preference is provided. This is a natural-language policy concern because the skill imposes Chinese output by default rather than offering a language choice or requiring explicit opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This i18n file hard-codes Chinese clinic names and directs the user to search for "JD皮肤科"/"jd clinic" across all booking channels, which constrains the skill to a specific language/locale context. The file does not offer any user choice or explain that this is intentionally a region- or clinic-specific skill, so it appears to impose that locale context by default.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

Line L08 says "请告诉我你的需求,我帮你处理 JD皮肤科 的预约", which is a very general invitation for users to state any need rather than a narrowly scoped activation description. In a manifest/i18n context, this kind of broad phrasing can blur when the skill should activate versus when it should not.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes a dermatology clinic skill focused on the clinic itself, especially booking and related information. Returning general BeautsGO app store and APK download links is a separate distribution/promotional capability that is not necessary to fulfill booking, pricing, or consultation for this clinic.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The parser explicitly extracts a user phone number from free-form input and stores it in the returned contact field. Although this is part of appointment handling, this file contains no user-facing disclosure, confirmation, or warning comment explaining that contact information will be parsed and used.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The function defaults the lang parameter to 'zh', which imposes a specific language choice when the caller does not explicitly select one. This is a natural-language locale policy concern because the skill does not indicate user choice or opt-in for the forced locale.

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