T09 · Insecure Skill Coding Practices
- Location
scripts/export-metrics.js:38- Finding
CSV Formula Injection in Metrics Export
- Content
View full analysis
Vulnerability Details
File Location:
scripts/export-metrics.js:38-42;scripts/analyze-tasks.js:221-225
Vulnerability Type: CSV Formula Injection and Improper CSV Escaping
Risk Level: MediumVulnerable Code
scripts/export-metrics.js:38-42:js const headers = Object.keys(data[0]).join(','); const rows = data.map(item => Object.values(item).map(v => `"${v}"`).join(',') ).join('\n'); const csv = headers + '\n' + rows;scripts/analyze-tasks.js:221-225:js } else if (format === 'csv') { const headers = Object.keys(metrics[0]).join(','); const rows = metrics.map(m => Object.values(m).join(',')).join('\n'); const csv = headers + '\n' + rows; const outputPath = path.join(outputDir, `zentao-report-${timestamp}.csv`);Technical Analysis
Both CSV generation implementations serialize values without neutralizing spreadsheet formula prefixes such as
=,+,-, and@. When a CSV file is opened in spreadsheet software, a cell beginning with one of these characters may be interpreted as a formula rather than plain text.Quoting a value, as done in
export-metrics.js, does not reliably prevent formula evaluation. That implementation also fails to escape embedded double quotes. The implementation inanalyze-tasks.jsdoes not quote or escape commas, quotes, carriage returns, or newlines at all, allowing malformed rows and potentially enabling additional cell-boundary manipulation.The directly exploitable input path is
export-metrics.js, which accepts an arbitrary JSON file through the--inputargument and exports its values to CSV. The analyzer currently uses hard-coded sample data, so external exploitation through that script is presently limited. However, its documented and intended design is to consume ZenTao API or database data, at which point attacker-controlled task or employee fields would reach the vulnerable CSV serializer.Attack Path
...[truncated 1578 chars]
- Remediation
View remediation
Remediation Suggestions
- Replace manual CSV construction with a maintained CSV serialization library that correctly handles commas, quotes, carriage returns, and newlines.
- Convert every value to a string and neutralize cells whose first non-whitespace character is
=,+,-, or@. A common defense is to prefix such values with an apostrophe before CSV serialization. - Apply the same protection to both headers and data values.
- Do not rely on surrounding a value with double quotes to prevent formula execution; CSV quoting controls field parsing, not spreadsheet formula interpretation.
- Validate imported JSON structure and reject unexpected nested objects or unsupported value types.
- Add automated tests covering:
- Formula-leading values
- Embedded double quotes
- Commas
- Carriage returns and newlines
- Leading whitespace before formula prefixes
- Null, undefined, object, and array values
- Apply the hardened serializer consistently in both
scripts/export-metrics.jsandscripts/analyze-tasks.jsbefore enabling real ZenTao API or database ingestion. - Document that exported reports may contain externally supplied text and should be opened using spreadsheet clients with external links and dangerous formula features disabled.
