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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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 }
);
  1. Warn before writing to directories that appear shared or globally writable.
  2. Define retention and secure-deletion procedures for generated payroll reports.
  3. 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
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 137)May include surrounding context.

md
node scripts/generate_band_offer_packet.js <input.json> <output-dir>

Missing User Warnings

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 172)May include surrounding context.

md
node scripts/generate_payroll_precheck_packet.js <input.json> <output-dir>

Vague Triggers

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

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

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.