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 plaintext distribution credential and instructs agents to collect and persist user API secrets in chat or text state.

Review before installing. Do not use this package with real QiQue credentials until the shipped distribution secret is removed and rotated, and the app_id/app_secret flow is replaced with a secure secret-entry and storage mechanism. The write-operation confirmation language is useful, but it does not address the credential exposure risk.

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

Hardcoded Distribution API Credential in Shipped Configuration

Content
View full analysis

Vulnerability Details

File Location: config/qique.config.json:4-5
Vulnerability Type: Hardcoded plaintext secret
Risk Level: High
Classification: T09: Insecure Skill Coding Practices

Vulnerable Code

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

The corresponding example configuration uses placeholder values, demonstrating that the values in the active configuration are not generic examples:

json
{
  "app_id": "your-app-id",
  "app_secret": "your-app-secret",
  "distribution_app_id": "your-distribution-app-id",
  "distribution_app_secret": "your-distribution-app-secret"
}

Technical Analysis

A distribution identifier and distribution secret are stored in plaintext in a configuration file shipped with the project. Anyone who obtains the package can recover these values without authentication.

The documented request protocol uses the exposed distribution secret as part of an MD5 request signature:

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

Consequently, the exposed secret is not merely descriptive configuration; it is authentication material used to construct valid API signatures. The API catalog documents operations involving customer profiles, chat histories, wallet records, orders, appointments, messages, coupons, delivery, and wallet changes.

Exploitation would also require a valid QiQue application credential unless the backend has an independent authentication weakness. Nevertheless, exposing one component of the signing credential materially weakens the authentication scheme and compromises the distribution identity.

Attack Path

  1. An attacker obtains the distributed Skill package or repository contents.
  2. The attacker reads config/qique.config.json.
  3. The attacker recovers the ...[truncated 1295 chars]
Remediation
View remediation

Remediation Suggestions

  1. Revoke and rotate the exposed distribution secret immediately.
  2. Review API access logs for unexpected requests associated with the exposed distribution identity.
  3. Remove populated credential files from the repository and all distributed artifacts.
  4. Purge the credential from version-control history where applicable.
  5. Store the replacement secret in a dedicated secret manager and inject it only at runtime.
  6. Restrict secret access to the minimum required service identity and tenant.
  7. Distribute only placeholder configuration templates.
  8. Add the populated configuration path to ignore rules.
  9. Enable automated secret scanning in local hooks and CI/CD pipelines.
  10. Consider replacing the custom MD5 signing design with a modern server-supported authentication mechanism using scoped, revocable, short-lived credentials.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:16
Finding

Unsafe Collection and Persistent Storage of User API Credentials

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:16-20 and SKILL.md:73-77
Additional Location: agents/openai.yaml:4
Vulnerability Type: Insecure handling and persistence of sensitive credentials
Risk Level: Medium
Classification: T09: Insecure Skill Coding Practices

Vulnerable Code

From SKILL.md:16-20:

markdown
## Prerequisites

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:73-77:

markdown
6. Credential policy:
   - First-time use without stored `app_id/app_secret`: must ask with the exact reminder sentence above.
   - 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 reinforces the requirement to retain user-provided credentials for future use and replace previously stored values when new credentials are supplied.

Technical Analysis

The Skill instructs the Agent to request API credentials through an ordinary conversation and then retain them in remembered session state or configuration text. It does not define or require:

  • Encryption at rest
  • A dedicated secret-management system
  • Tenant or user isolation
  • Access controls for stored state
  • Credential expiration or retention limits
  • Redaction from model context, transcripts, telemetry, or logs
  • A credential-deletion workflow
  • Explicit user consent for long-term retention

Preventing credentials from appearing in user-facing responses does not protect them from storage-layer exposure. Credentials submitted through chat may remain in conve ...[truncated 1979 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not request long-lived secrets through ordinary conversational messages.
  2. Use an authenticated secret-entry interface that prevents credentials from entering model prompts, chat transcripts, or telemetry.
  3. Store secrets in a dedicated secret manager with encryption at rest and strict access controls.
  4. Retain only opaque secret references in Agent memory or configuration.
  5. Isolate secrets by user, tenant, environment, and Agent execution context.
  6. Establish explicit expiration, rotation, revocation, and deletion procedures.
  7. Obtain informed user consent before retaining credentials.
  8. Redact secrets from logs, traces, error messages, backups, and debugging output.
  9. Prefer short-lived and narrowly scoped tokens over persistent application secrets.
  10. Remove instructions that authorize plaintext configuration storage or indefinite remembered-state retention.
  11. Provide users with a mechanism to inspect and delete stored credential references.
  12. Test for cross-session and cross-user secret disclosure before deployment.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (18)

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
98% confidence
Finding

The skill explicitly tells the agent to load credentials from local config or remembered session state and keep them persistent between turns. Persisting reusable API secrets in conversational memory or loosely defined config/state substantially raises the risk of secret leakage, unintended reuse across contexts, and compromise through prompt injection or memory exposure.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill directs the agent to ask the user for app_id and app_secret in plain conversation before any operation. Requesting long-lived API credentials through chat creates a clear secret-exfiltration and retention hazard, especially because agent transcripts may be logged, inspected, or later surfaced by other prompts/tools.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill requires storing newly provided secrets, reusing them later, and overwriting prior values when updated. This creates a persistent secret-management surface without specifying isolation, encryption, access control, or deletion guarantees, making credential theft or cross-session misuse much more likely.

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 assistant to 'long-term store' app_id and app_secret and reuse them later without re-prompting. Persistently retaining API credentials in conversational memory or uncontrolled storage expands the attack surface, increases the chance of secret leakage across sessions or users, and violates the principle of minimizing credential retention.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The description says to use the skill whenever an agent needs to answer or plan operations for QiQue business requests, then lists many broad business activities. This activation scope is expansive and does not provide clear exclusion conditions or negative examples, which can cause unintended invocation for ordinary support conversations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to request API credentials directly in normal conversation without an explicit warning about sensitivity, storage, or safer handling. In an LLM/agent environment, this increases the chance that users paste secrets into chat logs that may be retained, exposed to other tools, or mishandled downstream.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The prompt explicitly instructs the assistant to '使用纯文本协议输出', imposing a fixed output format/language behavior without offering the user a choice. Under the policy criteria, forcing a specific language or locale without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file states that the routing protocol converts 'Chinese natural-language intent', which imposes a specific language requirement in the skill's behavior. There is no indication of user opt-in, alternative language support, or a documented justification for a Chinese-only constraint.

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
88% confidence
Finding

The documentation explicitly enumerates four core credentials required for every API call but provides no guidance on secret storage, redaction, rotation, or prohibition on exposing them to the model/user-visible channel. In an agent skill context that performs customer, wallet, appointment, and messaging actions, this omission increases the chance that integrators will mishandle high-value secrets or pass them through prompts/logs, enabling unauthorized API access.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest describes the skill as operating in 'pure text protocol mode (no local executable dependency)', which suggests a documentation-level expectation of avoiding local system dependence. However, elsewhere the file instructs loading credentials from config/qique.config.json and persisting them to memory/config text state, which is a local state/config dependency rather than purely stateless text behavior.

Content

No source excerpt is available for this finding.