T09 · Insecure Skill Coding Practices
- Location
scripts/price_checker.py:173- Finding
Unescaped External Search Data Allows Markdown Content Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/price_checker.py, lines 173-177 and 196-201
Vulnerability Type: Markdown injection through unescaped product titles and unvalidated URLs
Risk Level: MediumVulnerable Code
python for i, product in enumerate(sorted_products[:10], 1): platform_name = self.PLATFORM_MAPPING.get( self._detect_platform(product.platform), {'name': product.platform} )['name'] price_display = f"¥{product.estimated_price:.2f}" if product.estimated_price else "未显示" title_snippet = product.title[:30] + "..." if len(product.title) > 30 else product.title row = f"| {i} | {platform_name} | {title_snippet} | {price_display} | [查看]({product.url}) |" report_lines.append(row)python for i, product in enumerate(sorted_products[:5], 1): platform_name = self.PLATFORM_MAPPING.get( self._detect_platform(product.platform), {'name': product.platform} )['name'] report_lines.extend([ f"### {i}. {platform_name}", f"- **商品**: {product.title}", f"- **价格**: ¥{product.estimated_price:.2f} (如果显示)" if product.estimated_price else "- **价格**: 未在摘要中显示", f"- **来源**: 搜索引擎索引结果", "" ])Technical Analysis
generate_report()treatsProductInfo.title,ProductInfo.platform, andProductInfo.urlas trusted values and directly interpolates them into a Markdown document. These fields are intended to originate from external search results, where listing publishers can control product titles and destination URLs.Markdown metacharacters, table separators, line breaks, headings, links, and images are not escaped. Consequently, a crafted title can terminate the intended table cell or list item and insert attacker-controlled report content. The destination URL is also placed inside a Markdown link without parsing its scheme or verifying that i ...[truncated 2047 chars]
- Remediation
View remediation
Remediation Suggestions
- Escape Markdown metacharacters in every externally sourced text field before interpolation, including product titles and platform names.
- Replace carriage returns and line feeds in values used inside tables or list items so an input value cannot create new Markdown blocks.
- Parse URLs with
urllib.parse.urlparse()and allow only thehttpsscheme. - Verify destination hosts against an explicit allowlist for the detected platform. Reject mismatches rather than displaying them as trusted platform links.
- Reject URLs containing credentials, control characters, malformed encoding, or unexpected schemes.
- Consider displaying validated URLs as plain text when the report renderer's link-scheme policy is unknown.
- Keep untrusted search snippets separate from authoritative recommendations and clearly label their origin.
- Add tests using titles containing pipes, brackets, parentheses, headings, image syntax, and line breaks, as well as URLs with disallowed schemes and unrelated hosts.
- Apply output encoding at the final rendering boundary if reports may also be converted to HTML.
