fix: 引入 v-dompurify-html 指令解决 v-html 的安全隐患

This commit is contained in:
puhui999 2023-05-31 15:58:35 +08:00
parent 2ddb605076
commit 6a10a81f58
8 changed files with 22 additions and 18 deletions

View File

@ -19,13 +19,13 @@ VITE_API_URL=/admin-api
VITE_BASE_PATH=/
# 是否删除debugger
VITE_DROP_DEBUGGER=false
VITE_DROP_DEBUGGER=true
# 是否删除console.log
VITE_DROP_CONSOLE=false
# 是否sourcemap
VITE_SOURCEMAP=true
VITE_SOURCEMAP=false
# 输出路径
VITE_OUT_DIR=dist-dev

View File

@ -64,6 +64,7 @@
"url": "^0.11.0",
"video.js": "^8.3.0",
"vue": "3.3.4",
"vue-dompurify-html": "^4.1.4",
"vue-i18n": "9.2.2",
"vue-router": "^4.1.6",
"vue-types": "^5.0.2",

View File

@ -1,16 +1,16 @@
<script lang="tsx">
import { PropType, defineComponent, ref, computed, unref, watch, onMounted } from 'vue'
import { ElForm, ElFormItem, ElRow, ElCol, ElTooltip } from 'element-plus'
import { computed, defineComponent, onMounted, PropType, ref, unref, watch } from 'vue'
import { ElCol, ElForm, ElFormItem, ElRow, ElTooltip } from 'element-plus'
import { componentMap } from './componentMap'
import { propTypes } from '@/utils/propTypes'
import { getSlot } from '@/utils/tsxHelper'
import {
setTextPlaceholder,
setGridProp,
setComponentProps,
setItemComponentSlots,
initModel,
setFormItemSlots
setComponentProps,
setFormItemSlots,
setGridProp,
setItemComponentSlots,
setTextPlaceholder
} from './helper'
import { useRenderSelect } from './components/useRenderSelect'
import { useRenderRadio } from './components/useRenderRadio'
@ -196,7 +196,7 @@ export default defineComponent({
<span>{item.label}</span>
<ElTooltip placement="right" raw-content>
{{
content: () => <span v-html={item.labelMessage}></span>,
content: () => <span v-dompurify-html={item.labelMessage}></span>,
default: () => (
<Icon
icon="ep:warning"

View File

@ -38,9 +38,10 @@ import App from './App.vue'
import './permission'
import '@/plugins/tongji' // 百度统计
import Logger from '@/utils/Logger'
import VueDOMPurifyHTML from 'vue-dompurify-html' // 解决v-html 的安全隐患
// 创建实例
const setupAll = async () => {
const app = createApp(App)
@ -61,6 +62,8 @@ const setupAll = async () => {
await router.isReady()
app.use(VueDOMPurifyHTML)
app.mount('#app')
}

View File

@ -16,20 +16,20 @@
</ContentWrap>
<!-- 弹窗表单预览 -->
<Dialog :title="dialogTitle" v-model="dialogVisible" max-height="600">
<div ref="editor" v-if="dialogVisible">
<Dialog v-model="dialogVisible" :title="dialogTitle" max-height="600">
<div v-if="dialogVisible" ref="editor">
<el-button style="float: right" @click="copy(formData)">
{{ t('common.copy') }}
</el-button>
<el-scrollbar height="580">
<div>
<pre><code class="hljs" v-html="highlightedCode(formData)"></code></pre>
<pre><code v-dompurify-html="highlightedCode(formData)" class="hljs"></code></pre>
</div>
</el-scrollbar>
</div>
</Dialog>
</template>
<script setup lang="ts" name="InfraBuild">
<script lang="ts" name="InfraBuild" setup>
import FcDesigner from '@form-create/designer'
import { useClipboard } from '@vueuse/core'
import { isString } from '@/utils/is'

View File

@ -46,7 +46,7 @@
{{ t('common.copy') }}
</el-button>
<div>
<pre><code class="hljs" v-html="highlightedCode(item)"></code></pre>
<pre><code v-dompurify-html="highlightedCode(item)" class="hljs"></code></pre>
</div>
</el-tab-pane>
</el-tabs>

View File

@ -19,7 +19,7 @@
>
<!-- 展示 HTML 内容 -->
<template #description="{ row }">
<div style="width: 600px" v-html="row.description"></div>
<div v-dompurify-html="row.description" style="width: 600px"></div>
</template>
</Descriptions>
</template>

View File

@ -3,7 +3,7 @@
<Descriptions :data="detailData" :schema="allSchemas.detailSchema">
<!-- 展示 HTML 内容 -->
<template #templateContent="{ row }">
<div v-html="row.templateContent"></div>
<div v-dompurify-html="row.templateContent"></div>
</template>
</Descriptions>
</Dialog>