Back to skill

Security audit

企雀医美系统-AI助手

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent QiQue business assistant, but it ships a credential-like distribution secret and tells the agent to collect and retain user API secrets.

Review before installing. Do not paste app secrets into chat or allow generic agent memory to retain them; use a protected secret manager or platform credential binding. The bundled distribution credential should be treated as exposed and rotated before production use. Keep write operations limited to explicitly confirmed customer, wallet, appointment, delivery, messaging, and coupon actions.

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

T09 · Insecure Skill Coding Practices

Error
Location
config/qique.config.json:4
Finding

Hard-Coded Distribution API Credential in Tracked Configuration

Content
View full analysis

Vulnerability Details

File Location: config/qique.config.json:4-5
Vulnerability Type: Hard-coded secret and plaintext credential exposure
Risk Level: High

Vulnerable Code

json
{
  "app_id": "",
  "app_secret": "",
  "distribution_app_id": "longxiaqique",
  "distribution_app_secret": "d91f6adabcbe6aaadbfe41162e4777d1"
}

Technical Analysis

The non-example configuration contains a hard-coded distribution identifier and a secret-looking 32-character value. According to references/methods.md, distributionAppSecret is incorporated into the signature of every API request:

text
sign = md5(appSecret + distributionAppSecret + concat(sorted(k+v)) + appSecret)

Committing this credential to the Skill package exposes it to every party able to download, inspect, archive, or redistribute the project. It may also remain accessible through repository history even if removed from the current version.

The exposed distribution secret alone does not provide a complete request-signing capability because an application secret is also required. However, it eliminates one factor from the signing scheme. An attacker who separately obtains a valid application credential can combine it with this value and the publicly documented signing procedure to construct apparently valid request signatures.

Attack Path

  1. An attacker obtains or downloads the Skill package.
  2. The attacker reads config/qique.config.json.
  3. The attacker extracts the distribution identifier and distribution secret.
  4. The attacker acquires a valid app_id and app_secret through another compromise, accidental disclosure, or unauthorized access.
  5. The attacker follows the signature algorithm documented in references/methods.md.
  6. The attacker constructs signed requests against the documented QiQue API endpoint.
  7. The privileges and accessible records are determined by the separately acquired application credentials and the server-side authorization model.

...[truncated 612 chars]

Remediation
View remediation

Remediation Suggestions

  1. Immediately revoke and rotate the exposed distribution secret.
  2. Remove the real value from the current tree and repository history.
  3. Retain only placeholders in distributed configuration files, consistent with config/qique.config.example.json.
  4. Load the secret at runtime from a managed secret store or a protected environment variable.
  5. Restrict secret access to the minimum required service identity and environment.
  6. Prevent credentials from entering logs, model prompts, generated output, diagnostic messages, or source-control commits.
  7. Add automated secret scanning to pre-commit hooks and continuous integration.
  8. Audit API and repository logs for prior unauthorized use or retrieval of the exposed value.
  9. Prefer a modern keyed message authentication construction if the upstream protocol can be changed. The existing custom MD5 construction should not be treated as a substitute for secure secret management.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:16
Finding

Unsafe Persistent Storage Policy for User-Supplied API Secrets

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:16-18 and SKILL.md:82-85; corroborated by agents/openai.yaml:4
Vulnerability Type: Insecure persistence and handling of sensitive credentials
Risk Level: Medium

Vulnerable Code

From SKILL.md:16-18:

text
1. Load credentials from `config/qique.config.json` (or remembered session state).
2. Keep credentials persistent between turns.
3. Never expose sensitive variables in any user-facing text.

From SKILL.md:82-85:

text
- After user provides new `app_id/app_secret`: persist to memory/config text state and reuse later.
- If user provides newer values later: overwrite the stored values.
- Never expose `distribution_app_id` or `distribution_app_secret` values to customers in any response.

The default Agent prompt in agents/openai.yaml:4 independently requires supplied credentials to be stored for later reuse.

Technical Analysis

The Skill instructs the Agent to collect an API secret and persist it either in remembered session state or configuration text. It does not define an approved storage mechanism, encryption requirements, tenant isolation, access controls, retention periods, deletion procedures, log redaction, or restrictions against writing secrets into project files.

Avoiding disclosure in user-facing text is insufficient to protect a secret at rest. Plaintext configuration, Agent memory, conversation records, telemetry, backups, and debug logs can all become secondary disclosure channels.

This is an insecure credential-management design rather than evidence of an implemented cross-session backdoor. The audited project contains no executable persistence code. Exploitability therefore depends on how the hosting Agent implements the instruction to persist memory or configuration state.

Attack Path

  1. A user supplies an app_id and app_secret as requested by the Skill.
  2. The Agent follows the instruction to retain the values in remembered state or conf ...[truncated 1237 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove instructions to persist secrets in generic Agent memory or plaintext configuration.
  2. Use a dedicated secret manager with encryption at rest and in transit.
  3. Scope each credential to a single tenant, user, environment, and minimum required set of API permissions.
  4. Store only a secret reference or opaque handle in conversational state.
  5. Define explicit retention, expiration, rotation, revocation, and secure-deletion policies.
  6. Require informed user consent before retaining credentials beyond the active operation.
  7. Redact secrets from prompts, transcripts, telemetry, exception reports, backups, and debug logs.
  8. Prevent the model from echoing any application or distribution credential, not only distribution credentials.
  9. Enforce access controls and tenant isolation at the storage layer rather than relying on prompt instructions.
  10. Add tests verifying that secrets cannot be recovered from subsequent unrelated sessions or users.
  11. Prefer short-lived, narrowly scoped tokens over long-lived application secrets where the upstream service supports them.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (16)

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.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill explicitly instructs the agent to load sensitive API credentials from config or remembered session state and to keep them persistent between turns. This creates a secret-handling channel in natural-language workflow where credentials may be retained, mishandled, or surfaced outside a dedicated secret-management boundary.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The workflow tells the agent to ask the user to provide app_id and app_secret directly in conversation before proceeding. Soliciting secrets in chat increases the chance of disclosure through logs, model context retention, transcript access, copy/paste mistakes, or prompt injection on later turns.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
100% confidence
Finding

The credential policy requires persisting newly supplied secrets to memory/config state and overwriting stored values with later user-provided secrets. Persisting conversationally supplied secrets to memory materially raises the risk of long-term exposure, unauthorized reuse across sessions, accidental leakage to other users or tools, and insecure storage in logs or config text.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly instructs the agent to store sensitive app_id and app_secret long-term and reuse them in future sessions. Indefinite persistence of API credentials increases the blast radius of prompt leakage, memory compromise, cross-session disclosure, and unauthorized actions against the QiQue backend, especially because these secrets enable business operations and data access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file contains natural-language instructions that explicitly route only Chinese business intent and mandates an exact Chinese-language reply when credentials are missing. Because the skill does not offer an opt-in language choice or document that it is intentionally limited to Chinese users, this appears to violate the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The prompt is entirely in Chinese and instructs the assistant with fixed behavior for interacting in that context, without offering the user any language or locale choice. This can violate language/locale policy when a skill implicitly forces one language rather than allowing user preference or documenting a justified regional constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The description states that the routing protocol converts Chinese natural-language intent, which imposes a specific language requirement. Under the policy, language constraints should either be optional for the user or clearly documented as a justified region- or compliance-specific limitation.

Content

No source excerpt is available for this finding.

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/methods.md (reported line 31)May include surrounding context.

md
## Write Operations

| SDK method             | Remote method       | HTTP | Key params                                                                                                                                                |
| ---------------------- | ------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `addCustomer`          | `addcustomer`       | POST | `name`, `telnum`, `erpId?`, `sex?`, `birthday?`, `channelName?`, `channelUserName?`, `preConsultName?`, `ownerName?`, `description?`                      |
| `changeWallet`         | `changewallet`      | POST | `telnum`, `type?`, `action?`, `changeNum?`, `remark?`, `sendNotify?`                                                                                      |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/methods.md (reported line 34)May include surrounding context.

md
| SDK method             | Remote method       | HTTP | Key params                                                                                                                                                |
| ---------------------- | ------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `addCustomer`          | `addcustomer`       | POST | `name`, `telnum`, `erpId?`, `sex?`, `birthday?`, `channelName?`, `channelUserName?`, `preConsultName?`, `ownerName?`, `description?`                      |
| `changeWallet`         | `changewallet`      | POST | `telnum`, `type?`, `action?`, `changeNum?`, `remark?`, `sendNotify?`                                                                                      |
| `offlineBuy`           | `offlinebuy`        | GET  | `telnum`, `pName`, `num`, `money?`, `buyTime?`                                                                                                            |
| `offlineExcute`        | `offlineexcute`     | GET  | `telnum`, `pName`, `num`, `excuteTime?`                                                                                                                   |
| `delivery`             | `delivery`          | GET  | `billId?`, `useCode?`, `detailIds?`, `deliveryCompany?`, `deliveryNumber?`, `deliveryComment?`, `type?`                                                   |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/methods.md (reported line 35)May include surrounding context.

md
| ---------------------- | ------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `addCustomer`          | `addcustomer`       | POST | `name`, `telnum`, `erpId?`, `sex?`, `birthday?`, `channelName?`, `channelUserName?`, `preConsultName?`, `ownerName?`, `description?`                      |
| `changeWallet`         | `changewallet`      | POST | `telnum`, `type?`, `action?`, `changeNum?`, `remark?`, `sendNotify?`                                                                                      |
| `offlineBuy`           | `offlinebuy`        | GET  | `telnum`, `pName`, `num`, `money?`, `buyTime?`                                                                                                            |
| `offlineExcute`        | `offlineexcute`     | GET  | `telnum`, `pName`, `num`, `excuteTime?`                                                                                                                   |
| `delivery`             | `delivery`          | GET  | `billId?`, `useCode?`, `detailIds?`, `deliveryCompany?`, `deliveryNumber?`, `deliveryComment?`, `type?`                                                   |
| `addOneAppointment`    | `addoneappointment` | GET  | `appointmentTime`, `pId`, plus one of `cusId` / `telnum`; optional `teamId`, `type`, `content`, `comment`, `appointmentTime1`, `doctorId`, `technicianId` |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/methods.md (reported line 36)May include surrounding context.

md
| `addCustomer`          | `addcustomer`       | POST | `name`, `telnum`, `erpId?`, `sex?`, `birthday?`, `channelName?`, `channelUserName?`, `preConsultName?`, `ownerName?`, `description?`                      |
| `changeWallet`         | `changewallet`      | POST | `telnum`, `type?`, `action?`, `changeNum?`, `remark?`, `sendNotify?`                                                                                      |
| `offlineBuy`           | `offlinebuy`        | GET  | `telnum`, `pName`, `num`, `money?`, `buyTime?`                                                                                                            |
| `offlineExcute`        | `offlineexcute`     | GET  | `telnum`, `pName`, `num`, `excuteTime?`                                                                                                                   |
| `delivery`             | `delivery`          | GET  | `billId?`, `useCode?`, `detailIds?`, `deliveryCompany?`, `deliveryNumber?`, `deliveryComment?`, `type?`                                                   |
| `addOneAppointment`    | `addoneappointment` | GET  | `appointmentTime`, `pId`, plus one of `cusId` / `telnum`; optional `teamId`, `type`, `content`, `comment`, `appointmentTime1`, `doctorId`, `technicianId` |
| `changeOneAppointment` | `changeappointment` | GET  | `id`, optional `teamId`, `type`, `content`, `comment`, `appointmentTime`, `appointmentTime1`, `pId`, `doctorId`, `technicianId`                           |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/methods.md (reported line 40)May include surrounding context.

md
| `delivery`             | `delivery`          | GET  | `billId?`, `useCode?`, `detailIds?`, `deliveryCompany?`, `deliveryNumber?`, `deliveryComment?`, `type?`                                                   |
| `addOneAppointment`    | `addoneappointment` | GET  | `appointmentTime`, `pId`, plus one of `cusId` / `telnum`; optional `teamId`, `type`, `content`, `comment`, `appointmentTime1`, `doctorId`, `technicianId` |
| `changeOneAppointment` | `changeappointment` | GET  | `id`, optional `teamId`, `type`, `content`, `comment`, `appointmentTime`, `appointmentTime1`, `pId`, `doctorId`, `technicianId`                           |
| `cancelOneAppointment` | `cancelappointment` | GET  | `id`, `comment?`                                                                                                                                          |
| `sendMsgTotel`         | `sendmsgtotel`      | GET  | `tel`, `type?`, `theParams?`                                                                                                                              |
| `sendCardOrCoupons`    | `sendcardorcoupons` | GET  | `cusId`, `cardOrCouponsId`                                                                                                                                |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/methods.md (reported line 41)May include surrounding context.

md
| `addOneAppointment`    | `addoneappointment` | GET  | `appointmentTime`, `pId`, plus one of `cusId` / `telnum`; optional `teamId`, `type`, `content`, `comment`, `appointmentTime1`, `doctorId`, `technicianId` |
| `changeOneAppointment` | `changeappointment` | GET  | `id`, optional `teamId`, `type`, `content`, `comment`, `appointmentTime`, `appointmentTime1`, `pId`, `doctorId`, `technicianId`                           |
| `cancelOneAppointment` | `cancelappointment` | GET  | `id`, `comment?`                                                                                                                                          |
| `sendMsgTotel`         | `sendmsgtotel`      | GET  | `tel`, `type?`, `theParams?`                                                                                                                              |
| `sendCardOrCoupons`    | `sendcardorcoupons` | GET  | `cusId`, `cardOrCouponsId`                                                                                                                                |

## Notes

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/methods.md (reported line 42)May include surrounding context.

md
| `changeOneAppointment` | `changeappointment` | GET  | `id`, optional `teamId`, `type`, `content`, `comment`, `appointmentTime`, `appointmentTime1`, `pId`, `doctorId`, `technicianId`                           |
| `cancelOneAppointment` | `cancelappointment` | GET  | `id`, `comment?`                                                                                                                                          |
| `sendMsgTotel`         | `sendmsgtotel`      | GET  | `tel`, `type?`, `theParams?`                                                                                                                              |
| `sendCardOrCoupons`    | `sendcardorcoupons` | GET  | `cusId`, `cardOrCouponsId`                                                                                                                                |

## Notes

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The document explicitly describes the credential contract and signature construction using appSecret and distributionAppSecret, but provides no handling restrictions, storage guidance, or warning not to expose these values in prompts, logs, or client-side contexts. In an agent skill that performs live business operations, this increases the chance of secret leakage or unsafe reuse, which could enable unauthorized API requests and tampering.

Content

No source excerpt is available for this finding.