fix: 修复xss漏洞。

This commit is contained in:
webb 2024-04-28 23:26:04 +08:00
parent cc62f98a9f
commit 4396c53d79
3 changed files with 52 additions and 4 deletions

View File

@ -17,6 +17,7 @@ import {
} from '@svgdotjs/svg.js' } from '@svgdotjs/svg.js'
import iconsSvg from '../../../svg/icons' import iconsSvg from '../../../svg/icons'
import { CONSTANTS } from '../../../constants/constant' import { CONSTANTS } from '../../../constants/constant'
import {defenseXSS} from "../../../utils/xss";
// 创建图片节点 // 创建图片节点
function createImgNode() { function createImgNode() {
@ -148,7 +149,7 @@ function createRichTextNode() {
text: text text: text
}) })
} }
let html = `<div>${this.getData('text')}</div>` let html = `<div>${defenseXSS(this.getData('text'))}</div>`
if (!this.mindMap.commonCaches.measureRichtextNodeTextSizeEl) { if (!this.mindMap.commonCaches.measureRichtextNodeTextSizeEl) {
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl = document.createElement('div') this.mindMap.commonCaches.measureRichtextNodeTextSizeEl = document.createElement('div')
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.position = 'fixed' this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.position = 'fixed'

View File

@ -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;
}

View File

@ -12,7 +12,8 @@
</template> </template>
<script> <script>
import { mapState } from 'vuex' import {mapState} from 'vuex'
import {defenseXSS} from 'simple-mind-map/src/utils/xss'
/** /**
* @Author: 王林 * @Author: 王林
@ -60,7 +61,7 @@ export default {
this.words = 0 this.words = 0
this.num = 0 this.num = 0
this.walk(data) this.walk(data)
countEl.innerHTML = this.textStr countEl.innerHTML = defenseXSS(this.textStr)
this.words = countEl.textContent.length this.words = countEl.textContent.length
}, },
@ -101,7 +102,7 @@ export default {
background: #262a2e; background: #262a2e;
.item { .item {
color: hsla(0,0%,100%,.6); color: hsla(0, 0%, 100%, .6);
} }
} }