T09 · Insecure Skill Coding Practices
- Location
scripts/generate_report.mjs:257- Finding
Untrusted API Content Is Rendered as Raw Markdown
- Content
View full analysis
Vulnerability Details
File Location:
scripts/generate_report.mjs, lines 257-277
Vulnerability Type: Untrusted content injection through unsafe Markdown rendering
Risk Level: MediumVulnerable Code
js for (const event of group) { const companyName = cleanCell(event.companyName || "未披露", 50); const rounds = Array.isArray(event.rounds) && event.rounds.length > 0 ? cleanCell(event.rounds.join("、"), 40) : "未披露"; const investors = Array.isArray(event.investors) && event.investors.length > 0 ? cleanCell(event.investors.join("、"), 60) : "未披露"; const intro = cleanCell(event.brief || "-", 110); const link = String(event.originalLink ?? "").trim(); const linkCell = link ? `[查看原文](${link})` : "-"; lines.push(`${index}. 公司简称:${companyName}`); lines.push(`轮次:${rounds}`); lines.push(`投资方:${investors}`); lines.push(`事件摘要:${intro}`); lines.push(`来源链接:${linkCell}`); lines.push(""); index += 1; }The affected values originate from the remote API and are preserved by
scripts/fetch_events.mjs, lines 282-305:js function normalizeEvent(item, index) { const brief = String(item?.brief ?? item?.description ?? "").trim(); const createdAt = String(item?.createdAt ?? "").trim(); const originalLink = String(item?.originalLink ?? "").trim(); const postTitle = String(item?.postTitle ?? item?.originalTitle ?? "").trim(); const tags = uniqueTagNames(item?.tags); if (!brief && !createdAt && !originalLink && !postTitle) { return { brief: "", createdAt: "", originalLink: "", postTitle: eventKey(item, index), tags: [], }; } return { brief, createdAt, originalLink, postTitle, tags, }; }Technical Analysis
Remote API fields such as the title, summary, tags, and source URL are treated as trusted report content. The
cleanCell()operation only normalizes whitespace and truncates text; it does not escape Markdown metacharacters or neutr ...[truncated 2277 chars]- Remediation
View remediation
Remediation Suggestions
- Escape Markdown metacharacters in every remotely sourced text field before interpolation, including company names, summaries, industries, rounds, investors, titles, and tags.
- Parse
originalLinkwith theURLAPI and allow only explicitly approved protocols, preferablyhttps:. - Consider restricting source links to an allowlist of expected domains when business requirements permit.
- Replace invalid or disallowed URLs with plain text rather than an actionable Markdown link.
- Remove control characters and other non-printing characters from API-provided fields.
- Clearly delimit fetched records as untrusted data in both generated output and agent instructions.
- Explicitly instruct the consuming agent not to execute or follow instructions contained in event fields.
- Add security tests covering Markdown headings, links, images, HTML, nested delimiters, control characters, unsafe URL schemes, phishing URLs, and prompt-injection-style payloads.
- Avoid requiring remote event entries to remain completely unchanged; preserve their meaning while safely encoding them for the output context.
