Back to skill

Security audit

ZJZ Workflow

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real accounting/tax skill, but it needs Review because it can handle payroll, tax, invoice, and banking actions with broad activation, sensitive data exposure, unsafe shell-style command templates, and unverified install/update guidance.

Install only after reviewing the publisher and CLI package carefully. Use this skill only for an intended 自记账 account, pin and verify the CLI version, avoid server-provided skill ZIP updates unless independently verified, confirm every write action, and avoid exposing full ID numbers, bank numbers, auth links, payroll, or invoice data in shell history, logs, screenshots, or chat unless necessary.

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

T08 · Insecure Dependencies

Warning
Location
SKILL.md:146
Finding
Unpinned Installation of a Privileged Third-Party CLI<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 146-153 **Vulnerability Type**: Unpinned and integrity-unverified package installation **Risk Level**: Medium ### Vulnerable Code ```markdown ## Dependencies Python packages (install once): ```shell pip install --upgrade zijizhang-cli ``` ⚠️ Requirement: `zijizhang-cli` version must be `0.0.28` or later ``` ### Technical Analysis The Skill instructs users or Agents to install the latest available version of `zijizhang-cli` using `pip install --upgrade`. It does not pin an exact audited version, verify a package hash, use a lockfile, or otherwise authenticate the installed artifact. A minimum-version requirement does not ensure that the package being installed is the version reviewed with this Skill. Because the CLI handles authentication state, company records, employee data, invoices, banking documents, payroll, and tax operations, it occupies a highly trusted position. If the package distribution account, registry release process, or another part of the dependency supply chain were compromised, this instruction could install modified code without warning. ### Attack Path 1. An attacker compromises the package publisher, release process, or package-distribution channel for `zijizhang-cli`. 2. The attacker publishes a malicious version satisfying the documented minimum version. 3. A user or Agent follows the Skill instructions and runs: ```shell pip install --upgrade zijizhang-cli ``` 4. `pip` resolves and installs the attacker-controlled release without checking an expected digest. 5. The malicious CLI executes during later account or financial operations. 6. It can access information supplied to the CLI, abuse locally stored authentication state, alter requests, or perform unauthorized actions with the user's existing account privileges. ### Impact Assessment Successful exploitation would execute dependency code with the operating-system privileges of the user runnin ...[truncated 495 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the open-ended upgrade command with an exact, reviewed version: ```shell python -m pip install 'zijizhang-cli==0.0.28' ``` 2. Publish and verify cryptographic hashes: ```shell python -m pip install --require-hashes -r requirements.txt ``` 3. Maintain a reviewed lockfile or requirements file containing the exact version and expected wheel hash. 4. Document the expected package index and package publisher identity. 5. Avoid automatically upgrading to newly published versions before they have been reviewed. 6. Prefer an isolated virtual environment rather than modifying a shared Python installation. 7. Re-review the CLI whenever the pinned dependency is updated. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:83
Finding
Unverified Update URL and Skill ZIP Replacement Process<![CDATA[ ## Vulnerability Details **File Locations**: - `SKILL.md`, lines 83-91 - `references/check_skill_update.md`, lines 62-68 **Vulnerability Type**: Unauthenticated remote update and supply-chain trust **Risk Level**: Medium ### Vulnerable Code From `SKILL.md`: ```markdown ```shell zijizhang-cli updater check_skill_update '0.0.2' ``` Processing rules (see `references/check_skill_update.md` for details): - `code != 200`: do not block the user's business request; continue using the current version and report that the remote update check failed - `code == 200` and `data.latest` is newer than the current version: the user must be prompted to upgrade/overwrite using `data.installation_guide_url` (do not guess the installation command or source; it is a ZIP package containing the Skill) - `must_be_update == true`: strongly instruct the user to upgrade before continuing workflows that may be affected by the version ``` From `references/check_skill_update.md`: ```markdown ### Processing Rules - When `code != 200`, continue with the current version and report that the remote update check was skipped. - When `code == 200` and `data.latest` is newer than `skill_version`, prompt the user to upgrade or overwrite the Skill using `data.installation_guide_url`. - When `must_be_update == true`, strongly instruct the user to upgrade before continuing potentially affected workflows. ``` The documented response example also places the download URL under server control: ```json { "code": 200, "msg": "ok", "data": { "latest": "0.0.3", "installation_guide_url": "https://res.zijizhang.com/download/skill/zijizhang-skill-0.0.3.zip", "must_be_update": false, "note": "..." } } ``` ### Technical Analysis The update process treats `installation_guide_url` returned by the installed CLI as authoritative. The instructions do not require: - An allowlisted update hostname. - Verification of the final URL after redirects. - A signed update manifest. - A ...[truncated 2188 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Allow updates only from a fixed, documented HTTPS hostname. 2. Reject unexpected schemes, hosts, ports, redirects, and URL credentials. 3. Return a signed update manifest containing: - Skill name. - Exact version. - Archive size. - SHA-256 or stronger digest. - Publication timestamp. 4. Verify the manifest using a public key pinned in the reviewed Skill. 5. Verify the archive digest before extraction or installation. 6. Validate archive entries against absolute paths, `..` traversal, symbolic-link escapes, and unexpected executable files. 7. Extract into a temporary staging directory and review the package manifest before replacing the active Skill. 8. Require explicit user approval after displaying the verified publisher, version, origin, and digest. 9. Do not treat an unsigned server-controlled `must_be_update` field as authoritative. 10. Provide a rollback mechanism for the previously reviewed Skill version. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
' --file_type='<file_type>' --bank_account_number_id='<id>' --billing_cycle='<billing_cycle>' ``` ```shell zijizhang-cli invoice upload_invoice_file --uid='<uid>' --file='<file>' ``` ### Technical Analysis The documentation represents user- or service-controlled values as text inserted directly into shell commands. Wrapping a placeholder in single quotes is not sufficient when the substituted value itself can contain an apostrophe. For example, employee JSON contains free-form string fields such as the ...[truncated 2320 chars]:3
Finding
Shell Command Injection Risk in CLI Command Templates<![CDATA[ ## Vulnerability Details **Primary File Location**: `references/add_employee.md`, lines 3-4 **Additional Affected Templates**: - `references/create_payroll.md`, lines 3-4 - `references/choose_bank_use.md`, lines 3-4 - `references/upload_bank_file.md`, lines 3-4 - `references/upload_invoice_file.md`, lines 3-4 **Vulnerability Type**: Shell command injection through unsafe interpolation **Risk Level**: High ### Vulnerable Code From `references/add_employee.md`: ```shell zijizhang-cli employee add_employee '<data>' --uid='<uid>' ``` Related templates include: ```shell zijizhang-cli payroll create_payroll '<month>' '<data>' --uid='<uid>' ``` ```shell zijizhang-cli bank choose_bank_use '<bill_id>' '<rule_text>' --uid='<uid>' ``` ```shell zijizhang-cli bank upload_bank_file --uid='<uid>' --file='<file>' --file_type='<file_type>' --bank_account_number_id='<id>' --billing_cycle='<billing_cycle>' ``` ```shell zijizhang-cli invoice upload_invoice_file --uid='<uid>' --file='<file>' ``` ### Technical Analysis The documentation represents user- or service-controlled values as text inserted directly into shell commands. Wrapping a placeholder in single quotes is not sufficient when the substituted value itself can contain an apostrophe. For example, employee JSON contains free-form string fields such as the employee name. Bank classification rules, payee data, search keywords, and local file paths may also contain user-controlled text. If an Agent constructs a command string by directly replacing placeholders and invokes it through a shell, a value containing an apostrophe can terminate the quoted argument. Shell operators placed after it may then be interpreted as commands. A conceptual malicious value could have the following shape: ```text value'; attacker-command; echo ' ``` This finding is conditional on the command being rendered as a shell string. If the execution framework always invokes the CLI using a structured argument vector without a s ...[truncated 1537 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prohibit execution through a shell and require argument-vector invocation, for example: ```python subprocess.run( [ "zijizhang-cli", "employee", "add_employee", json.dumps(employee_data), "--uid", uid, ], shell=False, check=True, ) ``` 2. Pass complex structured data through standard input or a validated JSON file rather than embedding it in a command string. 3. Do not recommend manual escaping as the primary defense; shell quoting is error-prone across platforms and shells. 4. Apply strict schema validation: - Validate UIDs and IDs against expected character sets. - Parse and validate dates rather than accepting arbitrary strings. - Restrict enum fields to documented values. - Validate numeric fields as numbers. 5. Resolve and validate upload paths using filesystem APIs. Confirm that each path is a regular file with an allowed extension. 6. Ensure server-returned strings are treated as data and never reused as executable command fragments. 7. Add adversarial tests covering apostrophes, semicolons, command substitutions, newlines, option-like values, and platform-specific metacharacters. 8. Update every workflow and reference template to state explicitly that placeholders must be passed as discrete process arguments rather than interpolated into a shell command. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (73)

Vague Triggers

High
Confidence
97% confidence
Finding
The skill description explicitly says it should trigger even when the user does not mention the 自记账 app, as long as the request resembles broad bookkeeping or tax tasks. In an agent setting, this overbroad activation can cause the skill to capture generic finance requests and drive account-bound CLI actions in the wrong context, increasing the risk of unintended access, data handling, or write operations against a sensitive bookkeeping system.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
整个技能描述与操作规范均默认以中文进行,且未说明可根据用户偏好切换语言或先征求语言选择。按规则,若技能强制特定语言而没有用户 opt-in,属于自然语言层面的语言/locale policy 风险。

Vague Triggers

Medium
Confidence
93% confidence
Finding
The 'When to Use This Skill' section lists broad categories such as payroll, employees, social security, invoices, tax filing, and financial reports without strong app-specific qualifiers. Because these are common business tasks, an orchestrator may route many unrelated requests into this skill, creating confusion, privacy risk, and potentially unsafe progression toward authenticated financial operations.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documentation instructs users to submit a bank account number via a CLI command but provides no warning that this is sensitive financial data, nor any guidance on secure handling such as avoiding shell history, logs, or screenshots. In an accounting and tax workflow, bank account numbers are high-sensitivity identifiers, so omission of handling precautions increases the risk of inadvertent disclosure during normal use.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The documentation instructs operators to submit highly sensitive employee personal data, including identity number, phone number, and birth-related information, but provides no privacy, minimization, masking, retention, or secure-handling guidance. In an accounting and payroll skill, this increases the chance of unnecessary exposure of regulated PII through shell history, logs, copied examples, and unsafe operator practices.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
All user-facing documentation in this file is written in Chinese, including the title, parameter descriptions, and return-field explanations, with no indication that other languages are supported or that Chinese is a region-specific requirement. This can violate language/locale policy when a skill imposes a specific language without user opt-in or documented justification.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This markdown file contains user-facing operational instructions exclusively in Chinese, and there is no indication that users may choose another language or that the skill is intentionally limited to a Chinese-speaking audience. Under the language/locale policy, forcing a specific language without opt-in is a natural-language policy violation.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documented command performs a state-changing accounting action by selecting a bank receipt usage/entry category, but the skill text provides no warning that it modifies financial records or that the action should be confirmed by the user. In an agent setting, this increases the risk of silent or unintended bookkeeping changes, especially because bill_id and rule_text directly affect accounting classification.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The documentation includes a direct quick-login URL and an associated `auth_key`, which together function as reusable authentication material. Even in an example, publishing a realistic live-looking token without any indication that it is redacted or invalid can enable unauthorized access if the credential is valid, and normalizes unsafe handling of login artifacts in a skill that manages sensitive accounting and tax operations.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The example exposes a JWT-like `auth_key` without labeling it as sensitive or warning against logging, sharing, or persisting it. In the context of a bookkeeping/tax skill, such a token could grant access to financial records or administrative actions, so omission of safe-handling guidance increases the risk of credential leakage and misuse.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation exposes a destructive command that deletes a bank account number but provides no warning, confirmation guidance, rollback note, or prerequisite validation steps. In a financial-accounting skill, this increases the chance of accidental or unauthorized deletion of sensitive banking configuration, which can disrupt payments, reconciliation, or tax/accounting workflows.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documentation explicitly shows retrieval and return of company tax numbers in a company list response, but provides no warning that this is sensitive business information or guidance on minimizing exposure. In an accounting/tax skill, these identifiers can enable privacy breaches, correlation of entities, and accidental disclosure through logs, screenshots, or downstream agent output.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation shows an employee-list API returning highly sensitive personal data, including full national ID numbers, phone numbers, birth dates, and salary information, without any warning about privacy, minimization, masking, or access-control expectations. In an accounting/payroll skill, this materially increases the risk of over-collection, unsafe downstream display, logging, or disclosure of employee PII if the command is used broadly or its output is exposed to users or other tools.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill explicitly recommends displaying full ID numbers (`zjhm`) in payroll output, and the example returns full identification numbers alongside salary and tax data. This exposes highly sensitive personal and financial information and increases the risk of privacy violations, insider misuse, and downstream data leakage in chat transcripts or logs.

Whitespace Padding

Medium
Category
Prompt Injection
Content
### 参数说明

| 参数    | 类型     | 必填 | 说明                                                                                          |
|:------|:-------|:---|:--------------------------------------------------------------------------------------------|
| month | string | ✅  | 工资单月份,如 2026-04                                                                             |
| uid   | string | ❌  | 公司唯一标识,可以不指定,如果不指定会用默认使用终端激活在用的`uid`,参见 `zijizhang-cli account get_cpy_list` 状态为 `true` 的公司 |
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.

Whitespace Padding

Medium
Category
Prompt Injection
Content
### 参数说明

| 参数    | 类型     | 必填 | 说明                                                                                          |
|:------|:-------|:---|:--------------------------------------------------------------------------------------------|
| month | string | ✅  | 工资单月份,如 2026-04                                                                             |
| uid   | string | ❌  | 公司唯一标识,可以不指定,如果不指定会用默认使用终端激活在用的`uid`,参见 `zijizhang-cli account get_cpy_list` 状态为 `true` 的公司 |
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.

Whitespace Padding

Medium
Category
Prompt Injection
Content
### 参数说明

| 参数    | 类型     | 必填 | 说明                                                                                          |
|:------|:-------|:---|:--------------------------------------------------------------------------------------------|
| month | string | ✅  | 工资单月份,如 2026-04                                                                             |
| uid   | string | ❌  | 公司唯一标识,可以不指定,如果不指定会用默认使用终端激活在用的`uid`,参见 `zijizhang-cli account get_cpy_list` 状态为 `true` 的公司 |
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.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill documentation explicitly instructs returning payroll preview data containing full employee names and full government ID numbers in normal output tables and examples. In a payroll/accounting context this is highly sensitive personal data, and exposing it without masking, minimization, or privacy warnings materially increases the risk of privacy breaches, insider misuse, accidental disclosure in chat logs, and noncompliance with data protection obligations.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This markdown file describes a command that returns invoice records including buyer/seller names, taxpayer identification numbers, and invoice numbers. The documentation does not include any warning that the output may contain sensitive financial or tax data, which is relevant for user privacy and safe handling.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| 参数               | 类型     | 必填 | 说明                                                                                            |
|:-----------------|:-------|:---|:----------------------------------------------------------------------------------------------|
| uid              | string | ❌  | 公司唯一标识,可以不指定;不指定时使用当前已切换在用的 `uid`,参见 `zijizhang-cli account get_cpy_list` 中 `active=true` |
| current          | int    | ❌  | 页码,默认 1                                                                                      |
| invoice_number   | string | ❌  | 发票号码关键字(精确匹配),不传则查询全部                                                                          |
| invoice_date_begin | string | ❌  | 开票日期开始,格式 `YYYY-MM-DD`(如需使用,需与 `invoice_date_end` 同时传)                                          |
| invoice_date_end | string | ❌  | 开票日期结束,格式 `YYYY-MM-DD`(如需使用,需与 `invoice_date_begin` 同时传)                                         |
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.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| 参数               | 类型     | 必填 | 说明                                                                                            |
|:-----------------|:-------|:---|:----------------------------------------------------------------------------------------------|
| uid              | string | ❌  | 公司唯一标识,可以不指定;不指定时使用当前已切换在用的 `uid`,参见 `zijizhang-cli account get_cpy_list` 中 `active=true` |
| current          | int    | ❌  | 页码,默认 1                                                                                      |
| invoice_number   | string | ❌  | 发票号码关键字(精确匹配),不传则查询全部                                                                          |
| invoice_date_begin | string | ❌  | 开票日期开始,格式 `YYYY-MM-DD`(如需使用,需与 `invoice_date_end` 同时传)                                          |
| invoice_date_end | string | ❌  | 开票日期结束,格式 `YYYY-MM-DD`(如需使用,需与 `invoice_date_begin` 同时传)                                         |
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.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| 参数               | 类型     | 必填 | 说明                                                                                            |
|:-----------------|:-------|:---|:----------------------------------------------------------------------------------------------|
| uid              | string | ❌  | 公司唯一标识,可以不指定;不指定时使用当前已切换在用的 `uid`,参见 `zijizhang-cli account get_cpy_list` 中 `active=true` |
| current          | int    | ❌  | 页码,默认 1                                                                                      |
| invoice_number   | string | ❌  | 发票号码关键字(精确匹配),不传则查询全部                                                                          |
| invoice_date_begin | string | ❌  | 开票日期开始,格式 `YYYY-MM-DD`(如需使用,需与 `invoice_date_end` 同时传)                                          |
| invoice_date_end | string | ❌  | 开票日期结束,格式 `YYYY-MM-DD`(如需使用,需与 `invoice_date_begin` 同时传)                                         |
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.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation describes a command that retrieves detailed individual tax and payroll data, including names, salary, deductions, and tax amounts, but provides no warning, consent requirements, access-control expectations, or privacy-handling guidance. In an accounting skill this access may be functionally legitimate, but the absence of safeguards in the skill documentation increases the risk of unauthorized disclosure or misuse of sensitive personal financial information.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The documentation is internally inconsistent: the command synopsis shows parameters like `goods_name`, `total_tax_price`, and `total_money`, the parameter table requires `invoice_id`, and the example uses `--invoice`. In an accounting/tax workflow, this can cause agents or users to submit the wrong identifier or omit the required one, leading to failed actions, misrouted invoice processing, or accidental operations on unintended records.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The document exposes a destructive payroll deletion command with no warning about irreversibility, no confirmation workflow, and no guidance to verify the target company or month before execution. In an accounting and tax context, accidental or unauthorized deletion of payroll data can disrupt compliance records, auditing, and downstream reporting, making the omission materially risky.

Static analysis

No suspicious patterns detected.