Back to skill

Security audit

定薪与申报检查助手 / Compensation Decision Assistant

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for HR compensation and payroll work, but it writes sensitive employee and pay data into local reports without enough safeguards.

Install only if you are prepared to handle the generated reports as confidential HR/payroll records. Use a restricted local directory, avoid shared or synced folders, redact direct identifiers where possible, and do not open generated CSV files from untrusted inputs until formula-injection hardening is added. Treat the payroll and compliance output as a precheck, not authoritative legal or payroll advice.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_band_offer_packet.js:18
Finding
CSV Formula Injection in Compensation Offer Export## Vulnerability Details **File Location**: `scripts/generate_band_offer_packet.js:18-22`, with the vulnerable export used at line 204 **Vulnerability Type**: CSV formula injection **Risk Level**: Medium ### Vulnerable Code ```js function csvEscape(value) { const str = safe(value); if (str.includes(",") || str.includes("\"") || str.includes("\n")) return `"${str.replace(/"/g, "\"\"")}"`; return str; } ``` The function is subsequently applied to user-controlled compensation fields: ```js fs.writeFileSync(trackerPath, `${header.join(",")}\n${row.map(csvEscape).join(",")}\n`, "utf8"); ``` ### Technical Analysis The `csvEscape` function implements delimiter and quotation escaping, but it does not neutralize spreadsheet formula prefixes. Values beginning with `=`, `+`, `-`, `@`, tab, or carriage return can be interpreted as formulas when the generated CSV is opened in spreadsheet software. Several exported fields originate from user-supplied JSON, including the candidate name, target role, expected compensation, and generated recommendation fields. Consequently, an attacker able to influence the input JSON could insert a formula payload into an exported cell. Quoting a malicious value is insufficient because common spreadsheet applications can still evaluate quoted CSV cells as formulas. ### Attack Path 1. An attacker supplies or modifies a compensation-review JSON document. 2. A user-controlled field, such as `candidate_name` or `job_title`, is set to a spreadsheet formula, for example a formula that creates a deceptive hyperlink or initiates a network request. 3. HR runs the documented command to generate the compensation packet. 4. `csvEscape` preserves the formula prefix and writes it to `band-offer-review.csv`. 5. A recipient opens the CSV in a spreadsheet application. 6. Depending on the spreadsheet client and its security configuration, the formula may be evaluated or presented as an actionabl ...[truncated 695 chars]
Remediation
## Remediation Suggestions 1. Detect values whose first significant character is `=`, `+`, `-`, or `@`, as well as values beginning with tab or carriage return. 2. Prefix such values with an apostrophe before applying ordinary CSV quoting. 3. Apply the protection to every externally influenced cell, not only names or free-text fields. 4. Consider generating XLSX instead of CSV and explicitly assign affected cells the string data type. 5. Add regression tests covering formulas both with and without leading whitespace. Example hardening: ```js function csvEscape(value) { let str = safe(value); if (/^[\t\r ]*[=+\-@]/.test(str)) { str = `'${str}`; } if (/[",\n\r]/.test(str)) { return `"${str.replace(/"/g, "\"\"")}"`; } return str; } ```

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_payroll_precheck_packet.js:21
Finding
CSV Formula Injection in Payroll Filing Export## Vulnerability Details **File Location**: `scripts/generate_payroll_precheck_packet.js:21-25`, with the vulnerable export used at lines 153-157 **Vulnerability Type**: CSV formula injection **Risk Level**: Medium ### Vulnerable Code ```js function csvEscape(value) { const str = safe(value); if (str.includes(",") || str.includes("\"") || str.includes("\n")) return `"${str.replace(/"/g, "\"\"")}"`; return str; } ``` The function is used when payroll findings are written to CSV: ```js fs.writeFileSync( trackerPath, `${header.join(",")}\n${rows.map((row) => row.map(csvEscape).join(",")).join("\n")}\n`, "utf8" ); ``` ### Technical Analysis The exporter quotes commas, quotation marks, and newlines, but it does not protect formula-capable values. Employee names and employee identifiers come directly from the supplied payroll JSON and are inserted into CSV cells. A field beginning with a spreadsheet formula indicator can therefore remain executable when the CSV is opened. This is a distinct attack surface from the compensation exporter because payroll CSV files are likely to be opened by HR, payroll, finance, or shared-services personnel with access to sensitive internal systems. ### Attack Path 1. An attacker influences a payroll import or causes a malicious value to appear in an employee name or employee identifier. 2. The value begins with a spreadsheet formula prefix such as `=`, `+`, `-`, or `@`. 3. HR runs the payroll precheck generator. 4. The formula is copied into `payroll-filing-precheck.csv` without neutralization. 5. A payroll or finance user opens the CSV in spreadsheet software. 6. The spreadsheet evaluates the formula or exposes an attacker-controlled interactive link, depending on client protections. ### Impact Assessment Potential impact includes: - Phishing or user redirection from a trusted payroll report. - Spreadsheet-based network requests and associated inf ...[truncated 376 chars]
Remediation
## Remediation Suggestions 1. Neutralize all cells beginning with formula prefixes, including prefixes appearing after whitespace, tabs, or carriage returns. 2. Perform neutralization before standard CSV quotation escaping. 3. Treat employee names and identifiers as untrusted even if they normally originate from internal systems. 4. Prefer XLSX output with explicit string cell types where operationally possible. 5. Add tests for payloads beginning with `=`, `+`, `-`, `@`, tab, carriage return, and leading spaces. 6. Document that existing CSV exports should not be opened without spreadsheet protected-view controls until regenerated with the fix. Example hardening: ```js function csvEscape(value) { let str = safe(value); if (/^[\t\r ]*[=+\-@]/.test(str)) { str = `'${str}`; } if (/[",\n\r]/.test(str)) { return `"${str.replace(/"/g, "\"\"")}"`; } return str; } ```

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_payroll_precheck_packet.js:169
Finding
Unnecessary Plaintext Duplication of Sensitive Payroll Records## Vulnerability Details **File Location**: `scripts/generate_payroll_precheck_packet.js:169-195` **Vulnerability Type**: Excessive plaintext storage of sensitive payroll and identity data **Risk Level**: Medium ### Vulnerable Code ```js fs.writeFileSync( jsonPath, JSON.stringify({ normalized_data: { meta: payload.meta, employees: payload.employees, issue_count: counts }, missing_information: missingFields, risk_summary: buildInternalMessage(highRiskEmployees), priority_issues: highRiskEmployees.map((item) => ({ employee_name: item.employee.employee_name, issues: item.issues.filter((issue) => issue.level === "high").map((issue) => issue.message) })), next_action: "先处理高风险人员和缺失字段,再进入正式申报。", message_draft: buildInternalMessage(highRiskEmployees), record_update: { payroll_month: payload.meta.payroll_month, legal_entity: payload.meta.legal_entity, high_risk_count: highRiskEmployees.length }, compliance_warning_if_any: highRiskEmployees.length ? ["存在高风险申报问题,建议先修正后申报。"] : [] }, null, 2), "utf8" ); ``` ### Technical Analysis The generated JSON places the complete `payload.employees` array into `normalized_data`. In production use, this array may contain: - Bank account details. - Government identity numbers. - Employee names and identifiers. - Salary and taxable-income values. - Social-insurance and housing-fund bases. - Employment and declaration status. The risk report only needs validation statuses, issue descriptions, and limited employee identifiers. Retaining the full source records creates a second plaintext copy of sensitive payroll data without a demonstrated functional requirement. The destination directory is selected through a command-line argument, and the code does not set restrictive file permissions. The resulting file can consequently inherit permissions affected by t ...[truncated 1281 chars]
Remediation
## Remediation Suggestions 1. Remove `employees: payload.employees` from the generated JSON. 2. Store only the minimum fields required for the report, such as an internal employee identifier, issue codes, severity, and remediation status. 3. Replace identity and bank-account values with validation states such as `present`, `missing`, or `invalid`. 4. If partial display is operationally required, mask all but a minimal number of characters. 5. Create sensitive output files with restrictive permissions: ```js fs.writeFileSync( jsonPath, JSON.stringify(minimizedOutput, null, 2), { encoding: "utf8", mode: 0o600 } ); ``` 6. Warn before writing to directories that appear shared or globally writable. 7. Define retention and secure-deletion procedures for generated payroll reports. 8. Keep detailed source payroll data separate from summary reports and enforce role-based access outside the generator.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (24)

Ae1

High
Category
analysis-evasion
Content
node scripts/generate_band_offer_packet.js <input.json> <output-dir>
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Missing User Warnings

High
Confidence
98% confidence
Finding
The payroll precheck export can include highly sensitive personal and payroll information such as employee names, status, entity, city, bank account status, ID status, tax, and social contribution fields, yet the skill provides no warning about local file creation or secure handling. In this context the danger is elevated because payroll and identity-related records are especially sensitive and may trigger privacy, employment, or regulatory exposure if written to insecure locations.

Ae1

High
Category
analysis-evasion
Content
node scripts/generate_payroll_precheck_packet.js <input.json> <output-dir>
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Vague Triggers

Medium
Confidence
92% confidence
Finding
The skill says to use it whenever the user is handling two broad categories of compensation work, covering common HR tasks like compensation decisions and filing checks. This lacks negative examples or explicit exclusions, so the activation scope may be wider than intended and could cause unintended invocation in ordinary HR conversations.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The routing logic activates based on very broad keyword presence, which can cause the skill to process unrelated or mixed HR conversations containing terms like tax, band, city, or budget. In a compensation and payroll context, misrouting can lead to unnecessary collection or processing of sensitive employee and payroll data, and may generate authoritative-looking outputs from incomplete context.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill instructs generating local output files for compensation review without warning where files will be written or that they may contain sensitive compensation, market, and internal peer data. This creates a real risk of accidental disclosure through insecure local paths, shared workstations, synced folders, or improperly permissioned directories.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The natural-language instruction on L4 is entirely in Chinese and directs how the assistant should respond, but the file does not offer a user-selectable language or state that the skill is region-specific. This creates a locale/language policy concern because the skill appears to impose a specific language by default rather than allowing user preference.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The CSV headers and sample recommendation content are entirely in Chinese, indicating the skill output is constrained to a specific language. There is no accompanying indication that the language choice is optional or justified by a region-specific requirement, which matches the language/locale policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
This JSON file contains user-facing natural-language fields such as prepared_by, field_issue, risk_summary, next_action, message_draft, and compliance_warning_if_any entirely in Chinese. Under the policy rule, forcing a specific language without opt-in or documented justification is a locale-policy violation, and this file does not indicate that the skill is region-locked or that users can choose another language.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
The CSV contains all issue messages and next-action text exclusively in Chinese, indicating a fixed language choice in user-facing content. For a general skill artifact, this can violate language/locale policy when no user choice or justification for the locale is provided.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This markdown file presents all operational guidance and policy knowledge exclusively in Chinese, and it does not state that the skill is China-only or that users can opt into this language. Under the policy rule, forcing a specific language without user choice or explicit justification is a natural-language policy violation.

Intent-Code Divergence

Medium
Confidence
89% confidence
Finding
The file states that `review_compensation_band_and_offer` cannot honestly provide compensation conclusions by 'just going online' and must require user-uploaded band, internal references, and market research. If the skill is presented as performing compensation review generally, this documentation narrows and conditions that capability in a way that conflicts with an unconditional manifest description.

Intent-Code Divergence

Medium
Confidence
92% confidence
Finding
This documentation explicitly states that the current compensation skill '还没有真正消费这份知识库' and is only a structural prototype, while the skill manifest describes it as helping HR with compensation review, band benchmarking, market checks, and payroll filing prechecks. That is an active contradiction between documented intent/capability and the described actual implementation status.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The document frames the workflow as '中国 HR 薪酬高频工作流' and the skill metadata also targets China-specific payroll, tax, social insurance, and housing fund processes without indicating that the skill is region-locked or requiring explicit user confirmation of jurisdiction. In an HR/payroll context, silently assuming the wrong locale can cause materially incorrect compliance guidance, filing checks, or compensation decisions, especially for multinational teams or ambiguous user requests.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill explicitly asks users to provide payroll, tax declaration, social insurance, housing fund, employee status, and legal-entity information, which are highly sensitive HR and personal data categories. Because the scenario text provides no minimization, redaction, consent, retention, or secure-handling warning, users may paste raw personal data into the agent, creating substantial privacy, compliance, and confidentiality risk.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The script embeds Chinese-only natural-language strings throughout its recommendations and generated documents, which forces a specific language/locale on all users. The policy allows locale constraints only when users are given a choice or when the restriction is clearly documented and justified.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script exports sensitive HR data—including candidate name, current and expected salary, internal band data, peer compensation references, and risk assessments—into multiple DOCX/CSV/JSON files without any consent check, minimization, masking, or warning. In an HR compensation workflow, this materially increases the chance of unintended retention, redistribution, or exposure of personal and confidential compensation information.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The script's generated messages, report titles, and issue descriptions are all hard-coded in Chinese, which imposes a specific language choice on users. There is no option to select another language and no documented justification that the skill is restricted to a Chinese-language or region-specific audience.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script creates multiple output artifacts for payroll precheck processing, including DOCX, CSV, and JSON files whose contents include employee names, employee IDs, and payroll/compliance issue details. Although the file's purpose is report generation, there is no visible confirmation prompt, warning comment, or user-facing disclosure that sensitive personnel data will be written to disk.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
This JSON sample uses Chinese legal entity, city, job titles, and free-text fields throughout, which can imply the skill expects or enforces a specific language/locale. Under the policy, locale constraints should be explicitly justified or offered as a user choice rather than implied by default sample content alone.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The file’s natural-language content is entirely in Chinese, including fields such as legal entity, notes, warnings, and recommendation text, but there is no indication that the skill offers a language choice or that the locale restriction is explicitly documented as intentional. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
This JSON sample uses Chinese-language values and China-specific entities/identifiers (for example the preparer role, legal entity, city, bank account and ID formats) without any accompanying indication that the skill is China-specific or that locale is configurable. That can constitute a natural-language locale policy issue because the sample implicitly constrains usage to one language/region without user opt-in or documented justification in the file.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
该文件全文仅以中文编写,且未见任何说明用户可选择其他语言,或该技能仅面向特定中文语境/地区用户。按照语言/地区策略,这属于未提供用户语言选择的潜在自然语言政策问题。

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The natural-language instructions, examples, and required outputs are all presented in Chinese, which effectively forces a specific language for use of the skill. There is no indication that users may choose another language or that the Chinese-only constraint is required for a documented region-specific purpose.

Static analysis

No suspicious patterns detected.