fix(security): 补全 XSS sanitize + 修复 sender_id 身份伪造

安全审计修复:
- 补全 6 个 DTO 的 sanitize 方法(diagnosis/consent/alert/medication_record/medication_reminder/follow_up_template)
- 4 个 handler 添加 .sanitize() 调用(diagnosis/consent/alert_rule/medication_record)
- 修复咨询消息 sender_id/sender_role 从客户端提交改为服务端从 JWT 提取
- 修复小程序 AI 报告 markdownToHtml XSS(添加 sanitizeHtml 过滤)
This commit is contained in:
iven
2026-04-30 10:21:52 +08:00
parent d8735eb45c
commit 931edc3025
15 changed files with 154 additions and 83 deletions

View File

@@ -12,8 +12,26 @@ const TYPE_LABELS: Record<string, string> = {
report_summary_generation: '报告摘要',
};
/** 移除危险的 HTML 标签和事件属性,防止 XSS */
function sanitizeHtml(html: string): string {
return html
// 移除 <script> 标签及其内容
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
// 移除 <iframe>, <object>, <embed>, <form>, <input>, <textarea>, <style> 标签
.replace(/<\/?(?:iframe|object|embed|form|input|textarea|style)\b[^>]*>/gi, '')
// 移除 <link> 和 <meta> 标签
.replace(/<\/?(?:link|meta)\b[^>]*>/gi, '')
// 移除所有 on* 事件属性 (onclick, onerror, onload 等)
.replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, '')
// 移除 javascript: 和 data: 协议的 href/src 属性
.replace(/(href|src)\s*=\s*(?:"javascript:[^"]*"|'javascript:[^']*')/gi, '')
.replace(/(href|src)\s*=\s*(?:"data:[^"]*"|'data:[^']*')/gi, '');
}
function markdownToHtml(md: string): string {
return md
// 先转义 markdown 中可能存在的原始 HTML 标签
const escaped = sanitizeHtml(md);
return escaped
.replace(/^### (.+)$/gm, '<h3>$1</h3>')
.replace(/^## (.+)$/gm, '<h2>$1</h2>')
.replace(/^# (.+)$/gm, '<h1>$1</h1>')