T09 · Insecure Skill Coding Practices
- Location
scripts/report.py:187- Finding
Unescaped Transaction Data Enables Markdown Content Injection and Potential Privacy Leakage
- Content
View full analysis
0: remaining = monthly_budget - spent pct = spent / monthly_budget * 100 pct_str = f"{pct:.0f}%" remaining_str = fmt_currency(remaining) if remaining >= 0 else f"**-{fmt_currency(abs(remaining))}**" alert = "⚠️" if spent > monthly_budget else ("🔶" if pct >= 80 else "✅") bar = bar_chart(spent, monthly_budget) lines.append(f"| {category} | {fmt_currency(spent)} | {fmt_currency(monthly_budget)} | {remaining_str} | {pct_str} | {alert} {bar} |") else: lines.append(f"| {category} | {fmt_currency(spent)} | — | — | — | — |") else: pct = fmt_pct(spent, stats["total_spent"]) lines.append(f"| {category} | {fmt_currency(spent)} | {pct} |") lines.append("") # Budget alerts if budget: overages = [] warnings = [] for category, monthly_b ...[truncated 4312 chars]- Remediation
View remediation
str: text = str(value) text = text.replace("\\", "\\\\") text = text.replace("|", "\\|") text = text.replace("\r", " ").replace("\n", " ") text = text.replace("<", "<").replace(">", ">") return text ``` 2. Apply the escaping function to all transaction-derived and configuration-derived fields before interpolation, including: - Merchant descriptions - Categories - Month labels derived from input dates - Budget category names - Source filenames 3. Neutralize Markdown image and link syntax where practical. For merchant and category labels, consider rendering escaped inline code rather than unrestricted Markdown. 4. Reject or normalize control characters during CSV and JSON ingestion. Newlines, carriage returns, null bytes, and other non-printable characters should not be retained in descriptions or categories. 5. Serialize YAML frontmatter with a proper YAML library or strictly sanitize and quote all values inserted into frontmatter. The source filename and month values should not be interpolated as raw YAML. 6. Add security regression tests using values such as: ```text  [Click here](https://attacker.example/) Merchant | Injected column Merchant ## Fabricated Section ``` The tests should verify that these values render only as inert text and cannot create links, images, HTML elements, new rows, or new sections. 7. Document that imported CSV and JSON files are untrusted inputs. As defense in depth, advise users to keep remote resource loading disabled in their Markdown viewer. ]]>
