chore: src/modules/knowledge/utils/xss.ts
This commit is contained in:
@@ -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, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归转义对象中的所有字符串字段
|
||||||
|
* @param obj 输入对象
|
||||||
|
* @param excludeFields 排除的字段列表(这些字段不转义,如富文本、JSON等)
|
||||||
|
* @returns 转义后的对象
|
||||||
|
*/
|
||||||
|
export function escapeObject<T = any>(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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user