From 0b7780a091827ce6fe446e9dd0e5f18181dd4568 Mon Sep 17 00:00:00 2001 From: snowgitea Date: Wed, 1 Jul 2026 17:45:00 +0800 Subject: [PATCH] chore: src/modules/knowledge/utils/xss.ts --- src/modules/knowledge/utils/xss.ts | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/modules/knowledge/utils/xss.ts diff --git a/src/modules/knowledge/utils/xss.ts b/src/modules/knowledge/utils/xss.ts new file mode 100644 index 0000000..d2aafdf --- /dev/null +++ b/src/modules/knowledge/utils/xss.ts @@ -0,0 +1,55 @@ +/** + * XSS 防护工具 - 对用户输入进行 HTML 实体转义 + * 防止存储型 XSS 攻击,作为纵深防御的一环 + */ + +/** + * HTML 实体转义 + * 将特殊字符转换为 HTML 实体,防止脚本注入 + * @param str 输入字符串 + * @returns 转义后的字符串 + */ +export function escapeHtml(str: string): string { + if (!str || typeof str !== 'string') { + return str; + } + return str + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +/** + * 递归转义对象中的所有字符串字段 + * @param obj 输入对象 + * @param excludeFields 排除的字段列表(这些字段不转义,如富文本、JSON等) + * @returns 转义后的对象 + */ +export function escapeObject(obj: T, excludeFields: string[] = []): T { + if (obj === null || obj === undefined) { + return obj; + } + + if (typeof obj === 'string') { + return escapeHtml(obj) as unknown as T; + } + + if (Array.isArray(obj)) { + return obj.map((item) => escapeObject(item, excludeFields)) as unknown as T; + } + + if (typeof obj === 'object') { + const result = { ...obj }; + for (const key in result) { + if (excludeFields.includes(key)) { + continue; + } + result[key] = escapeObject(result[key], excludeFields); + } + return result as T; + } + + return obj; +}