T09 · Insecure Skill Coding Practices
- Location
scripts/render-demo-report.mjs:10- Finding
Untrusted External Metadata Is Rendered Without Sufficient Markdown Sanitization
- Content
View full analysis
"---").join(" | ")} |`; const body = rows.map((row) => `| ${headers.map((headerName) => String(row[headerName] ?? "").replace(/\|/g, "\\|")).join(" | ")} |`); return [header, sep, ...body].join("\n"); } ``` The affected function is used with remotely controlled GitHub and npm metadata: ```js ${table(docIssues.slice(0, 7).map((issue) => ({ title: issue.title, labels: issue.labels.length > 0 ? issue.labels.join(", ") : "-", comments: issue.comments, source: issue.html_url, })))} ``` ```js ${table(npmPackages.slice(0, 8).map((pkg) => ({ package: pkg.name, version: pkg.version, weekly_downloads: compactNumber(pkg.downloads_weekly), monthly_downloads: compactNumber(pkg.downloads_monthly), updated: pkg.date, source: pkg.links?.npm ?? pkg.links?.repository ?? "", })))} ``` ### Technical Analysis The table renderer treats metadata obtained from GitHub and the npm registry as trusted Markdown. It escapes only the pipe character used as a table-column delimiter. It does not neutralize: - Markdown link or image syntax; - embedded HTML; - carriage returns and line feeds; - other Markdown control characters; - unsafe or unexpected URL schemes; - excessively long values. An attacker who controls an issue title, label, package metadata field, or package link could supply content interpreted by a Markdown renderer rather than displayed as plain text. Depending on the Markdown viewer, this could produce deceptive links, remote tracking images ...[truncated 1605 chars]- Remediation
View remediation
]*>/g, "") .slice(0, maxLength) .replace(/([\\`*_{}\[\]()#+.!|>-])/g, "\\$1"); } function safeHttpsUrl(value) { try { const url = new URL(String(value)); return url.protocol === "https:" ? url.href : ""; } catch { return ""; } } ``` Apply context-specific encoding separately to display text and URLs. ]]>
