mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-14 08:15:53 +08:00
fix: sanitizer svg to avoid xss (#16608)
This commit is contained in:
parent
acd7fead87
commit
061a765b7d
@ -10,6 +10,7 @@ import SyntaxHighlighter from 'react-syntax-highlighter'
|
|||||||
import { atelierHeathLight } from 'react-syntax-highlighter/dist/esm/styles/hljs'
|
import { atelierHeathLight } from 'react-syntax-highlighter/dist/esm/styles/hljs'
|
||||||
import { Component, memo, useMemo, useRef, useState } from 'react'
|
import { Component, memo, useMemo, useRef, useState } from 'react'
|
||||||
import type { CodeComponent } from 'react-markdown/lib/ast-to-react'
|
import type { CodeComponent } from 'react-markdown/lib/ast-to-react'
|
||||||
|
import SVGRenderer from './svg-gallery'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
import CopyBtn from '@/app/components/base/copy-btn'
|
import CopyBtn from '@/app/components/base/copy-btn'
|
||||||
import SVGBtn from '@/app/components/base/svg'
|
import SVGBtn from '@/app/components/base/svg'
|
||||||
@ -118,13 +119,13 @@ const CodeBlock: CodeComponent = memo(({ inline, className, children, ...props }
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// else if (language === 'svg' && isSVG) {
|
else if (language === 'svg' && isSVG) {
|
||||||
// return (
|
return (
|
||||||
// <ErrorBoundary>
|
<ErrorBoundary>
|
||||||
// <SVGRenderer content={content} />
|
<SVGRenderer content={content} />
|
||||||
// </ErrorBoundary>
|
</ErrorBoundary>
|
||||||
// )
|
)
|
||||||
// }
|
}
|
||||||
else {
|
else {
|
||||||
return (
|
return (
|
||||||
<SyntaxHighlighter
|
<SyntaxHighlighter
|
||||||
@ -224,16 +225,8 @@ const Link = ({ node, ...props }: any) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeSVGTags(htmlString: string): string {
|
|
||||||
return htmlString.replace(/(<svg[\s\S]*?>)([\s\S]*?)(<\/svg>)/gi, (match: string, openTag: string, innerContent: string, closeTag: string): string => {
|
|
||||||
return openTag.replace(/</g, '<').replace(/>/g, '>')
|
|
||||||
+ innerContent.replace(/</g, '<').replace(/>/g, '>')
|
|
||||||
+ closeTag.replace(/</g, '<').replace(/>/g, '>')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Markdown(props: { content: string; className?: string }) {
|
export function Markdown(props: { content: string; className?: string }) {
|
||||||
const latexContent = preprocessLaTeX(escapeSVGTags(props.content))
|
const latexContent = preprocessLaTeX(props.content)
|
||||||
return (
|
return (
|
||||||
<div className={cn(props.className, 'markdown-body')}>
|
<div className={cn(props.className, 'markdown-body')}>
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { SVG } from '@svgdotjs/svg.js'
|
import { SVG } from '@svgdotjs/svg.js'
|
||||||
|
import DOMPurify from 'dompurify'
|
||||||
import ImagePreview from '@/app/components/base/image-uploader/image-preview'
|
import ImagePreview from '@/app/components/base/image-uploader/image-preview'
|
||||||
|
|
||||||
export const SVGRenderer = ({ content }: { content: string }) => {
|
export const SVGRenderer = ({ content }: { content: string }) => {
|
||||||
@ -44,7 +45,7 @@ export const SVGRenderer = ({ content }: { content: string }) => {
|
|||||||
|
|
||||||
svgRef.current.style.width = `${Math.min(originalWidth, 298)}px`
|
svgRef.current.style.width = `${Math.min(originalWidth, 298)}px`
|
||||||
|
|
||||||
const rootElement = draw.svg(content)
|
const rootElement = draw.svg(DOMPurify.sanitize(content))
|
||||||
|
|
||||||
rootElement.click(() => {
|
rootElement.click(() => {
|
||||||
setImagePreview(svgToDataURL(svgElement as Element))
|
setImagePreview(svgToDataURL(svgElement as Element))
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"decimal.js": "^10.4.3",
|
"decimal.js": "^10.4.3",
|
||||||
|
"dompurify": "^3.2.4",
|
||||||
"echarts": "^5.5.1",
|
"echarts": "^5.5.1",
|
||||||
"echarts-for-react": "^3.0.2",
|
"echarts-for-react": "^3.0.2",
|
||||||
"elkjs": "^0.9.3",
|
"elkjs": "^0.9.3",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user