diff --git a/web/app/components/base/markdown.tsx b/web/app/components/base/markdown.tsx index 90d6225484..7cda904d96 100644 --- a/web/app/components/base/markdown.tsx +++ b/web/app/components/base/markdown.tsx @@ -21,7 +21,6 @@ import ImageGallery from '@/app/components/base/image-gallery' import { useChatContext } from '@/app/components/base/chat/chat/context' import VideoGallery from '@/app/components/base/video-gallery' import AudioGallery from '@/app/components/base/audio-gallery' -import SVGRenderer from '@/app/components/base/svg-gallery' import MarkdownButton from '@/app/components/base/markdown-blocks/button' import MarkdownForm from '@/app/components/base/markdown-blocks/form' import ThinkBlock from '@/app/components/base/markdown-blocks/think-block' @@ -137,13 +136,14 @@ const CodeBlock: any = memo(({ inline, className, children, ...props }: any) => ) } - else if (language === 'svg' && isSVG) { - return ( - - - - ) - } + // Attention: SVGRenderer has xss vulnerability + // else if (language === 'svg' && isSVG) { + // return ( + // + // + // + // ) + // } else { return (
{(['mermaid', 'svg']).includes(language!) && } - +
@@ -240,11 +240,20 @@ const Link = ({ node, ...props }: any) => { } } +function escapeSVGTags(htmlString: string): string { + return htmlString.replace(/()([\s\S]*?)(<\/svg>)/gi, (match: string, openTag: string, innerContent: string, closeTag: string): string => { + return openTag.replace(//g, '>') + + innerContent.replace(//g, '>') + + closeTag.replace(//g, '>') + }) +} + export function Markdown(props: { content: string; className?: string; customDisallowedElements?: string[] }) { const latexContent = flow([ preprocessThinkTag, preprocessLaTeX, - ])(props.content) + ])(escapeSVGTags(props.content)) + return (