diff --git a/simple-mind-map/src/core/render/node/nodeCreateContents.js b/simple-mind-map/src/core/render/node/nodeCreateContents.js
index cd2dd183..b7464dab 100644
--- a/simple-mind-map/src/core/render/node/nodeCreateContents.js
+++ b/simple-mind-map/src/core/render/node/nodeCreateContents.js
@@ -17,6 +17,7 @@ import {
} from '@svgdotjs/svg.js'
import iconsSvg from '../../../svg/icons'
import { CONSTANTS } from '../../../constants/constant'
+import {defenseXSS} from "../../../utils/xss";
// 创建图片节点
function createImgNode() {
@@ -148,7 +149,7 @@ function createRichTextNode() {
text: text
})
}
- let html = `
${this.getData('text')}
`
+ let html = `${defenseXSS(this.getData('text'))}
`
if (!this.mindMap.commonCaches.measureRichtextNodeTextSizeEl) {
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl = document.createElement('div')
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.position = 'fixed'
diff --git a/simple-mind-map/src/utils/xss.js b/simple-mind-map/src/utils/xss.js
new file mode 100644
index 00000000..afd92bd2
--- /dev/null
+++ b/simple-mind-map/src/utils/xss.js
@@ -0,0 +1,46 @@
+/**
+ * 防御 XSS 攻击,过滤恶意 HTML 标签和属性
+ * @param {string} text 需要过滤的文本
+ * @returns {string} 过滤后的文本
+ */
+export function defenseXSS(text) {
+ // 初始化结果变量
+ let result = text;
+
+ // 使用正则表达式匹配 HTML 标签
+ const match = text.match(/<(\S*?)[^>]*>.*?|<.*? \/>/g);
+ if (match == null) {
+ // 如果没有匹配到任何标签,则直接返回原始文本
+ return text;
+ }
+
+ // 遍历匹配到的标签
+ for (let value of match) {
+ // 定义白名单属性正则表达式(style、target、href)
+ const whiteAttrRegex = new RegExp(/(style|target|href)=["'][^"']*["']/g);
+
+ // 定义黑名单href正则表达式(javascript:)
+ const aHrefBlackRegex = new RegExp(/href=["']javascript:/g);
+
+ // 过滤 HTML 标签
+ const filterHtml = value.replace(
+ // 匹配属性键值对(如:key="value")
+ /([a-zA-Z-]+)\s*=\s*["']([^"']*)["']/g,
+ (text) => {
+ // 如果属性值包含黑名单href或不在白名单中,则删除该属性
+ if (aHrefBlackRegex.test(text) || !whiteAttrRegex.test(text)) {
+ return "";
+ }
+
+ // 否则,保留该属性
+ return text;
+ }
+ );
+
+ // 将过滤后的标签替换回原始文本
+ result = result.replace(value, filterHtml);
+ }
+
+ // 返回最终结果
+ return result;
+}
\ No newline at end of file
diff --git a/web/src/pages/Edit/components/Count.vue b/web/src/pages/Edit/components/Count.vue
index 2b752ba1..75bddfa8 100644
--- a/web/src/pages/Edit/components/Count.vue
+++ b/web/src/pages/Edit/components/Count.vue
@@ -12,7 +12,8 @@