T09 · Insecure Skill Coding Practices
- 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-167andscripts/generate_interview_packet.js:246-250
Vulnerability Type: CSV formula injection
Risk Level: MediumVulnerable 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
csvEscapefunction 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
- 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.
- A recruiter places that value into the input JSON and runs
generate_interview_packet.js. - The script passes the malicious value through
csvEscape, which only performs ordinary CSV syntax escaping. - The formula is written to `candidate-tracker-update.c ...[truncated 1284 chars]
- Remediation
View remediation
Remediation Suggestions
- Detect formula-leading characters after accounting for leading spaces, tabs, carriage returns, and other control characters.
- Neutralize dangerous cells by prefixing them with an apostrophe or another mechanism appropriate for the target spreadsheet application.
- Apply formula neutralization before ordinary CSV quoting and escaping.
- Use a maintained CSV serialization library and explicitly enable spreadsheet-injection protection where available.
- Validate and constrain structured fields such as candidate names, tracker stages, and owner names.
- Add regression tests for cells beginning with
=,+,-,@, tab, carriage return, and whitespace followed by those characters. - 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; }
