Back to skill

Security audit

Compensation Repo

Security checks for vulnerabilities and agentic risk

Overview

This HR skill is relevant to its stated purpose, but it can write sensitive payroll and compensation details into local plaintext report files without adequate warning or safeguards.

Use this only in a controlled HR environment. Before generating packets, choose a private output directory, avoid shared drives, review files before forwarding, and delete or retain them according to payroll and employee-data policy. Be especially careful opening generated CSV files in spreadsheet software if any input data could come from an untrusted source.

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

Warning
Location
scripts/generate_payroll_precheck_packet.js:164
Finding

Sensitive Payroll and Identity Data Is Duplicated into Plaintext Output

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_payroll_precheck_packet.js, lines 164–171
Vulnerability Type: Plaintext storage and unnecessary duplication of sensitive personal data
Risk Level: Medium

Vulnerable Code

javascript
normalized_data: {
  meta: payload.meta,
  employees: payload.employees,
  issue_count: counts
},
missing_information: missingFields,
risk_summary: buildInternalMessage(highRiskEmployees),
priority_issues: highRiskEmployees.map((item) => ({

The full payload.employees array is placed into normalized_data and subsequently serialized into payroll-filing-precheck-output.json. Employee input records can contain identity numbers, bank account numbers, salary information, legal entities, and filing details. The sample input demonstrates that bank_account and id_number are part of these records.

Technical Analysis

The payroll check only needs to determine whether sensitive fields are present and valid. It does not need to reproduce their complete values in the generated JSON report. Copying the entire employee objects creates an additional plaintext data repository without data minimization, field-level redaction, encryption, explicit restrictive permissions, or retention controls.

The output filename is predictable and the output directory is selected through a command-line argument. The script creates that directory using the process's normal permissions but does not explicitly restrict the generated file to its owner. Consequently, the effective exposure depends on directory ownership, process umask, shared storage configuration, backups, and subsequent distribution of the report packet.

Attack Path

  1. An HR operator prepares an input JSON file containing real employee bank account numbers, identity numbers, compensation data, and filing details.
  2. The operator runs the documented payroll packet generator.
  3. The script copies every employ ...[truncated 891 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not include complete employee objects in generated reports. Emit only the minimum fields required for remediation, such as an internal employee identifier and validation statuses.
  2. Replace sensitive values with booleans or status fields, for example:
    • bank_account_status: "present"
    • id_number_status: "missing"
  3. If partial identification is operationally necessary, retain only masked values or a short suffix and ensure that it cannot reconstruct the original identifier.
  4. Build an explicit output schema rather than serializing payload.employees directly.
  5. Create files with owner-only permissions where supported, such as mode 0o600, and verify that the output directory is not broadly accessible.
  6. Document retention, deletion, sharing, and backup requirements for generated payroll packets.
  7. Add automated tests that fail if prohibited keys such as id_number or bank_account appear in generated JSON.
  8. Consider encryption at rest when reports must contain regulated personal information.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_payroll_precheck_packet.js:15
Finding

Formula Injection Is Possible in Generated CSV Reports

Content
View full analysis

Vulnerability Details

File Locations:

  • scripts/generate_payroll_precheck_packet.js, lines 15–19 and 152–160
  • scripts/generate_band_offer_packet.js, lines 20–24 and 199–209

Vulnerability Type: CSV or spreadsheet formula injection
Risk Level: Medium

Vulnerable Code

Payroll report escaping and output:

javascript
function csvEscape(value) {
  const str = safe(value);
  if (str.includes(",") || str.includes("\"") || str.includes("\n")) return `"${str.replace(/"/g, "\"\"")}"`;
  return str;
}
javascript
const header = ["employee_name", "employee_id", "risk_level", "issue_message", "next_action"];
const rows = analyzed.flatMap((item) =>
  item.issues.map((issue) => [
    item.employee.employee_name,
    item.employee.employee_id,
    issue.level,
    issue.message,
    issue.level === "high" ? "优先处理并复核后再申报" : "复核后决定是否继续申报"
  ])
);
fs.writeFileSync(
  trackerPath,
  `${header.join(",")}\n${rows.map((row) => row.map(csvEscape).join(",")).join("\n")}\n`,
  "utf8"
);

Compensation report escaping and output:

javascript
function csvEscape(value) {
  const str = safe(value);
  if (str.includes(",") || str.includes("\"") || str.includes("\n")) return `"${str.replace(/"/g, "\"\"")}"`;
  return str;
}
javascript
const header = ["candidate_name", "target_role", "expected_monthly_base", "band_position", "suggested_base", "recommendation_strength", "risk_flags", "recommendation"];
const row = [
  candidate.candidate_name,
  payload.position.job_title,
  candidate.expected_monthly_base,
  result.bandPosition,
  result.suggestedBase,
  result.recommendationStrength,
  result.risks.join(";"),
  result.recommendation
];
fs.writeFileSync(trackerPath, `${header.join(",")}\n${row.map(csvEscape).join(",")}\n`, "utf8");

Technical Analysis

The csvEscape function correctly quotes commas, quotation marks, and newlines, ...[truncated 2450 chars]

Remediation
View remediation

Remediation Suggestions

  1. Apply spreadsheet-formula neutralization to every untrusted CSV cell before standard CSV quoting.
  2. After converting a value to a string, detect dangerous first characters, including =, +, -, and @.
  3. Account for leading spaces, tabs, carriage returns, and other characters that spreadsheet applications may ignore before formula detection.
  4. Prefix dangerous values with a single quotation mark or another application-compatible neutralization character before applying normal CSV escaping.
  5. Consider rejecting control characters that are not operationally required.
  6. Apply the same hardened helper consistently in both report generators.
  7. Add test cases covering direct and whitespace-prefixed formulas, embedded quotation marks, commas, newlines, tabs, and carriage returns.
  8. Where practical, generate a structured spreadsheet format using a maintained library and explicitly mark untrusted cells as strings. The library's behavior must still be verified because type inference can reintroduce formula interpretation.
  9. Advise users to open reports in protected mode, but do not rely on user behavior as the primary control.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (21)

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 packet generation step can write highly sensitive employee filing data to disk, including names, status, legal entity, city, bank/account status, ID status, tax, and social contribution fields, but the skill provides no warning or consent checkpoint. In an HR/payroll context this materially raises privacy, data leakage, and compliance exposure if the export path is shared, persistent, or improperly secured.

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>

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The document directs users to a China compensation policy knowledge base for latest policy and system guidance, and the surrounding instructions are primarily Chinese-oriented, but it does not explicitly offer language or locale choice. This can constitute a language/locale policy issue when the skill implicitly assumes a single locale without opt-in or clear limitation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger says the skill should activate when input contains tax, social insurance, housing fund filing fields, or monthly filing lists, employee status, or entity information. These terms are common across routine HR conversations, and the document does not provide exclusions or tighter scope boundaries for when the skill should not route to this action.

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 generate output files for compensation review data without warning that sensitive HR data may be written to local storage. In this context, the files can contain compensation bands, candidate pay, internal peer references, and budget information, creating confidentiality and retention risks if written to an uncontrolled path.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The default prompt at L4 is written as an instruction to respond in Chinese and does not indicate that the user may choose another language. This creates a locale/language policy concern because the skill appears to impose a language preference without explicit user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

This JSON artifact is entirely structured around Chinese-language content and labels, including workflow outputs, messages, and warnings, with no indication that language selection is user-configurable or limited to a justified China-specific compliance context. Per the policy, a skill that effectively enforces a specific language without opt-in can be 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
84% confidence
Finding

This JSON file contains user-facing natural-language fields entirely in Chinese, including workflow metadata and warning/message text, without any indication that the skill offers language choice or that the output is intentionally restricted to a China-specific audience. Under the policy, forcing a specific language without opt-in can be a locale-policy violation unless the constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This CSV contains all user-facing issue messages and next-action guidance exclusively in Chinese, with no indication that language selection is optional or region-specific. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation applicable to all file types.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This markdown file presents all operational guidance and policy knowledge exclusively in Chinese and does not indicate any user choice, opt-in, or justified locale restriction. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file is explicitly framed as '中国 HR 薪酬高频工作流' and describes payroll, tax, social insurance, and housing fund processes specific to China without an explicit scope gate, user confirmation, or warning that the guidance is jurisdiction-specific. In an HR/payroll skill, applying country-specific compliance logic to the wrong employee population or legal entity can cause incorrect compensation decisions or filing-precheck outputs, leading to regulatory and operational errors.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The generated report titles, bullets, risk messages, and recommendation text are all fixed in Chinese, which forces a specific language/locale on output. There is no opt-in, configuration, or documentation indicating that the skill is intentionally limited to Chinese-language use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script writes highly sensitive HR data, including candidate name, current and expected salary, internal banding, peer compensation averages, and hiring recommendations, into multiple plaintext and document outputs with no minimization, access controls, masking, retention warning, or consent/disclosure mechanism. In an HR compensation workflow this materially increases the chance of unauthorized disclosure, over-sharing, accidental forwarding, or persistence of sensitive payroll and employee-equity data across files and recipients.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code generates user-facing messages, report titles, bullets, and issue descriptions entirely in Chinese string literals. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly documented and justified, which is not present in this file.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This JSON file appears to be a manifest/data file for a compensation review workflow, but it does not describe when the skill should or should not activate, nor does it provide any explicit trigger phrases or exclusion conditions. Under the vague-trigger rule for manifest files, the absence of trigger specificity can allow overly broad or unintended invocation in systems that infer activation from file metadata.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This JSON sample uses Chinese-language values and a China-specific legal entity/currency/city context, but provides no natural-language indication that the skill is intended specifically for Chinese HR compensation workflows. If the surrounding skill is expected to be generally applicable, this can amount to an implicit locale constraint without user opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This JSON contains multiple user-facing natural-language fields such as notes, risk summaries, next actions, and message drafts entirely in Chinese. Because the file does not indicate that the skill is China-specific or that the user opted into Chinese, it may violate the policy against forcing a specific language without user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The file’s natural-language content, including headers and recommendation text, is entirely in Chinese with no indication that language selection is configurable or intentionally limited to a region-specific workflow. Under the policy, fixed language behavior without user opt-in can be a locale-policy issue when no justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This JSON sample uses Chinese-language values and China-specific entities throughout, such as Chinese names, legal entities, and city names. For SQP-3, this can be a natural-language locale constraint because the file implicitly fixes a single locale without any documented user choice or justification in the file itself.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

该文件全文以中文撰写,并未说明这是面向特定中文用户群体的区域性文档,也没有提供语言选择或用户 opt-in。按照语言/locale 政策,若技能内容默认强制单一语言而无选择或正当说明,属于自然语言层面的政策风险。

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.