Back to skill

Security audit

招聘推进助手 / Recruiting Follow-up Copilot

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent China-focused recruiting assistant, but its CSV exporters can preserve spreadsheet formulas from candidate data while writing sensitive HR records to disk.

Review before installing. Use it only for recruiting data you are allowed to process, choose a controlled output directory, redact salary or interview details when not needed, and avoid opening generated CSV files in spreadsheet tools until formula-injection hardening is added or the CSV is sanitized.

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_interview_packet.js:160
Finding

CSV Formula Injection in Interview Tracker Export

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_interview_packet.js:160-167 and scripts/generate_interview_packet.js:246-250
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;
}
js
fs.writeFileSync(
  trackerPath,
  `${trackerHeader.join(",")}\n${trackerRow.map(csvEscape).join(",")}\n`,
  "utf8"
);

Technical Analysis

The csvEscape function escapes CSV delimiters, quotation marks, and newline characters, but it does not neutralize spreadsheet formulas. Values beginning with =, +, -, or @ can be interpreted as formulas when the generated CSV is opened in formula-evaluating spreadsheet software.

The affected tracker row contains data derived from the input JSON, including the candidate name, target role, tracker stage, owner name, and summaries derived from interview feedback. These values may originate from resumes, imported tracker records, interview notes, chat transcripts, or other untrusted sources.

Quoting a dangerous cell is not a sufficient defense because common spreadsheet applications may still evaluate quoted CSV fields as formulas. Leading whitespace, tab characters, and carriage returns may also be used to bypass checks that only inspect the first untrimmed character.

Attack Path

  1. An attacker submits a crafted candidate field or causes a malicious value to appear in imported interview data, such as a candidate name beginning with a spreadsheet formula.
  2. A recruiter places that value into the input JSON and runs generate_interview_packet.js.
  3. The script passes the malicious value through csvEscape, which only performs ordinary CSV syntax escaping.
  4. The formula is written to `candidate-tracker-update.c ...[truncated 1284 chars]
Remediation
View remediation

Remediation Suggestions

  1. Detect formula-leading characters after accounting for leading spaces, tabs, carriage returns, and other control characters.
  2. Neutralize dangerous cells by prefixing them with an apostrophe or another mechanism appropriate for the target spreadsheet application.
  3. Apply formula neutralization before ordinary CSV quoting and escaping.
  4. Use a maintained CSV serialization library and explicitly enable spreadsheet-injection protection where available.
  5. Validate and constrain structured fields such as candidate names, tracker stages, and owner names.
  6. Add regression tests for cells beginning with =, +, -, @, tab, carriage return, and whitespace followed by those characters.
  7. Document that exported recruiting data must be treated as untrusted when opened in spreadsheet applications.

Example hardening approach:

js
function csvEscape(value) {
  let str = safe(value);

  if (/^[\s\x00-\x1F]*[=+\-@]/.test(str)) {
    str = `'${str}`;
  }

  if (str.includes(",") || str.includes("\"") || str.includes("\n")) {
    return `"${str.replace(/"/g, "\"\"")}"`;
  }

  return str;
}

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_screening_packet.js:137
Finding

CSV Formula Injection in Resume Screening Tracker Export

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_screening_packet.js:137-141 and scripts/generate_screening_packet.js:212
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;
}
js
fs.writeFileSync(
  trackerPath,
  `${trackerHeader.join(",")}\n${trackerRow.map(csvEscape).join(",")}\n`,
  "utf8"
);

Technical Analysis

The resume-screening generator serializes attacker-influenced candidate and job data into a CSV tracker row. Its escaping routine protects CSV structure but does not protect spreadsheet consumers from formula injection.

Candidate names, job titles, tracker stages, and HR owner names are copied directly from the input payload. The last-update summary also incorporates candidate and job information. If any such value begins with =, +, -, or @, a spreadsheet application may treat it as an executable formula rather than plain text.

This risk is especially relevant because resumes and candidate profiles are externally supplied content, while the generated file is expressly intended for use in ATS systems or spreadsheets. CSV quoting alone does not reliably prevent formula evaluation.

Attack Path

  1. A malicious candidate places a spreadsheet formula in a resume-derived field, or an attacker introduces one through an imported profile or tracker value.
  2. An HR operator transfers the value into the screening input JSON.
  3. The operator runs generate_screening_packet.js.
  4. The script serializes the malicious value with csvEscape, which does not neutralize formula prefixes.
  5. The value is written to resume-screening-update.csv.
  6. A recruiter opens or imports the CSV in a formula-evaluating spreadsheet application.
  7. The app ...[truncated 827 chars]
Remediation
View remediation

Remediation Suggestions

  1. Treat every value originating from resumes, job descriptions, tracker metadata, and user-provided JSON as untrusted.
  2. Before CSV serialization, neutralize values whose first meaningful character is =, +, -, or @.
  3. Account for leading whitespace and control characters that may conceal a formula prefix.
  4. Preserve normal RFC-compatible CSV escaping after formula neutralization.
  5. Use a vetted CSV library with explicit spreadsheet-injection mitigation when possible.
  6. Add automated tests covering direct and whitespace-prefixed formula payloads in every exported tracker field.
  7. Consider generating XLSX files with cells explicitly typed as text if spreadsheet compatibility is a primary requirement.

Example hardening approach:

js
function csvEscape(value) {
  let str = safe(value);

  if (/^[\s\x00-\x1F]*[=+\-@]/.test(str)) {
    str = `'${str}`;
  }

  if (str.includes(",") || str.includes("\"") || str.includes("\n")) {
    return `"${str.replace(/"/g, "\"\"")}"`;
  }

  return str;
}
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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 (15)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
4. [scripts/generate_interview_packet.js](scripts/generate_interview_packet.js)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
4. [scripts/generate_interview_packet.js](scripts/generate_interview_packet.js)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
5. [scripts/generate_screening_packet.js](scripts/generate_screening_packet.js)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
5. [scripts/generate_screening_packet.js](scripts/generate_screening_packet.js)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation guidance is broadly scoped to general recruiting tasks like feedback summaries, candidate communication, offer prep, and tracker updates without clear gating conditions or confirmation steps. In an agent environment, this can cause the skill to activate on loosely related HR conversations and steer the model into processing sensitive candidate data or initiating operational outputs when the user may have only wanted advice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill explicitly instructs local execution of scripts that generate DOCX and CSV artifacts and references write-back behavior, but it does not require an explicit user confirmation or warn that local files may be created or existing tracker data paths may be used. In practice, this increases the risk of unintended local data modification, export of sensitive recruiting information, or confusion about where candidate data is being written.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The default prompt says '优先输出简体中文' ('prioritize Simplified Chinese'), which imposes a language preference by default. This is a natural-language policy issue because the file does not offer the user a language choice or indicate that the locale constraint is optional or justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language fields in the generated output are entirely in Chinese, including the decision summary, next action, and candidate message draft, with no indication that the user opted into Chinese or that the skill is region-specific. This can violate language/locale policy when a skill implicitly forces a specific language without offering user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The natural-language fields decision_summary, next_action, and message_draft are written entirely in Chinese, and the file provides no indication that this language was selected by the user or justified as a region-specific requirement. This can violate language/locale policy when a skill forces a specific language without 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 file contains natural-language content entirely in Chinese, including role names, decisions, and next steps, with no indication that the skill supports multiple languages or that Chinese is required for a region-specific workflow. Under the policy, forcing a specific language without user opt-in can be a locale-policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This JSON sample is entirely scoped to a Chinese recruiting context, with Chinese-language values for candidate, job, and interview feedback fields. For a generally named workflow like "summarize_interview_feedback," this can encode an implicit locale/language requirement without any accompanying note that the skill is China-specific or that users may supply other languages/locales.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The document centers the skill on Chinese-language recruiting scenarios and uses Chinese trigger phrases and China-specific tooling/context as the default workflow. Because it does not offer an opt-in or alternative language/locale behavior, it may violate the policy against forcing a specific language or locale without user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script hardcodes Chinese punctuation, Chinese decision labels, Chinese document titles, and Chinese candidate-facing/internal messaging throughout the generated outputs. There is no indication that the user can select language or that the skill is intentionally limited to a Chinese-language or region-specific workflow.

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 recruiting data, including candidate identity, employer, salary expectation, interview feedback, and hiring decisions, into multiple files on disk without any minimization, consent check, access control, retention control, or warning. In an HR workflow context this materially increases privacy and confidentiality risk because the generated DOCX, CSV, and JSON artifacts are easy to copy, sync, or ingest into downstream systems, exposing PII and confidential interview assessments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This JSON sample includes locale-specific natural-language content such as "china internet recruiting" and Chinese-only field values/names, which can imply the skill is oriented to a specific language/locale by default. Under the policy, locale constraints should be justified or offered as a user choice rather than silently enforced.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.