T09 · Insecure Skill Coding Practices
- Location
scripts/parse_orders.py:579- Finding
Unescaped Spreadsheet Values Allow Markdown Report Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/parse_orders.py, lines 579–614; spreadsheet values originate at lines 459–463
Vulnerability Type: Markdown injection through untrusted spreadsheet fields
Risk Level: MediumVulnerable Code
python # By platform if results['by_platform']: md.append("\n## 🌍 按平台汇总") md.append("| 平台 | 订单 | 收入 | 平台支出 | 订单成本 | 净利润 | 利润率 |") md.append("|------|------|------|---------|---------|--------|--------|") for k, d in sorted(results['by_platform'].items(), key=lambda x: x[1]['profit'], reverse=True): m = (d['profit'] / d['income'] * 100) if d['income'] != 0 else 0 md.append(f"| {k} | {d['count']} | ¥{d['income']:,.2f} | ¥{d['expense']:,.2f} | ¥{d['cost']:,.2f} | ¥{d['profit']:,.2f} | {m:.1f}% |") # By store if results['by_store']: md.append("\n## 🏪 按店铺汇总") md.append("| 店铺 | 订单 | 收入 | 平台支出 | 订单成本 | 净利润 | 利润率 |") md.append("|------|------|------|---------|---------|--------|--------|") for k, d in sorted(results['by_store'].items(), key=lambda x: x[1]['profit'], reverse=True): m = (d['profit'] / d['income'] * 100) if d['income'] != 0 else 0 md.append(f"| {k} | {d['count']} | ¥{d['income']:,.2f} | ¥{d['expense']:,.2f} | ¥{d['cost']:,.2f} | ¥{d['profit']:,.2f} | {m:.1f}% |") # Top/bottom orders = results['orders'] if orders: bottom5 = orders[:5] top5 = orders[-5:][::-1] md.append("\n## 🔴 亏损最严重的5单") md.append("| # | 订单号 | 平台 | 店铺 | 收入 | 支出 | 成本 | 净利润 |") md.append("|---|--------|------|------|------|------|------|--------|") for i, o in enumerate(bottom5, 1): md.append(f"| {i} | {o['order_no'][:18]} | {o['platform']} | {o['store'][:8]} | ¥{o['platform_income']:,.2f} | ¥{o['platform_expense']:,.2f} | ¥{o['order_cost']:,.2f} | 🔴 ¥{o['net_profit_calc']:,.2f} |") md.append("\n## 🟢 盈利最高的5单") md.append("| # | 订单号 | 平台 | 店铺 | 收入 | 支出 | 成本 | 净利润 ...[truncated 2679 chars]- Remediation
View remediation
Remediation Suggestions
-
Implement one centralized escaping function for all workbook-derived values before placing them in Markdown:
python def escape_markdown_table(value): text = str(value or '') text = text.replace('\\', '\\\\') text = text.replace('|', '\\|') text = text.replace('\r', ' ').replace('\n', ' ') text = text.replace('<', '&lt;').replace('>', '&gt;') return text -
Apply the function to every untrusted textual field, including order numbers, platform names, store names, SKUs, statuses, and aggregation keys.
-
Prefer a structured report-generation library that performs contextual escaping rather than constructing Markdown through direct interpolation.
-
Configure the intended Markdown renderer to reject raw HTML and disable remote image or resource loading.
-
Add tests containing vertical bars, CR/LF characters, Markdown links and images, HTML tags, backslashes, and unusually long cell values.
-
If reports are converted to HTML, apply HTML escaping at the conversion boundary and enforce an appropriate Content Security Policy.
-
