T09 · Insecure Skill Coding Practices
- Location
index.js:409- Finding
Unescaped Spreadsheet Fields Permit Markdown Report Injection
- Content
View full analysis
{ const amount = t.amount > 0 ? `+¥${formatNumber(t.amount)}` : `-¥${formatNumber(Math.abs(t.amount))}`; const type = t.amount > 0 ? '💰 收入' : '💸 支出'; report += `| ${idx+1} | ${t.date || '-'} | ${t.counterparty || '-'} | ${amount} | ${type} | ${t.summary || '-'} |\n`; }); report += '\n'; ``` The company name is also inserted into a Markdown heading without escaping: ```javascript report += `### ${company}\n\n`; ``` The resulting attacker-influenced report is then written to disk: ```javascript fs.writeFileSync(reportPath, report, 'utf8'); ``` ### Technical Analysis Fields such as transaction date, counterparty, summary, and company name originate from a user-selected CSV or XLSX file. These values are interpolated directly into Markdown tables and headings without escaping Markdown metacharacters, removing line breaks, rejecting raw HTML, or validating URL-bearing constructs. An attacker can place pipes, newlines, headings, links, images, or raw HTML in spreadsheet cells. When the report is generated, these constructs become part of its Markdown structure. This can allow an attacker to: - Break out of a table cell. - Add fabricated financial findings or risk warnings. - Insert deceptive links. - Embed remote images or other externally loaded resources. - Misrepresent the source and conclusions of the financial analysis. For example, a company or summary field could contain: ```markdown Legitimate Company ## Approved Financial Conclusion  ``` The exact behavior depends on the Markdown viewer. Markdown itself does not generally grant arbitrary local code execution, but viewers that load remote resources may make a networ ...[truncated 1477 chars]- Remediation
View remediation
/g, '>') .replace(/!/g, '\\!') .replace(/\[/g, '\\[') .replace(/\]/g, '\\]'); } ``` 2. Use the escaping function for dates, counterparties, summaries, company names, and all other spreadsheet-derived text: ```javascript report += `| ${idx + 1} | ${escapeMarkdownCell(t.date)} | ${escapeMarkdownCell(t.counterparty)} | ${amount} | ${type} | ${escapeMarkdownCell(t.summary)} |\n`; ``` 3. Use a separate heading-safe encoder for company names, or avoid using untrusted values as Markdown headings. 4. Reject or neutralize raw HTML and URL-bearing image syntax if the report does not require them. 5. Impose reasonable field-length limits to prevent oversized or misleading report content. 6. Add security tests containing pipes, CR/LF characters, headings, links, image syntax, and raw HTML in every imported textual field. 7. Configure the intended Markdown viewer or export pipeline to disable raw HTML and remote resource loading where possible. ]]>
