mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-08-08 08:28:02 +08:00
fix(chunk): render <img> tags as escaped text to prevent tracking (#18007)
This commit is contained in:
@@ -9,9 +9,9 @@ import {
|
||||
} from '@/components/ui/tooltip';
|
||||
import type { ChunkDocType, IChunk } from '@/interfaces/database/dataset';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { sanitizeHtmlWithImagesAsText } from '@/utils/dom-util';
|
||||
import { CheckedState } from '@radix-ui/react-checkbox';
|
||||
import classNames from 'classnames';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ChunkTextMode } from '../../constant';
|
||||
@@ -128,7 +128,7 @@ const ChunkCard = ({
|
||||
>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: DOMPurify.sanitize(item.content_with_weight).trim(),
|
||||
__html: sanitizeHtmlWithImagesAsText(item.content_with_weight).trim(),
|
||||
}}
|
||||
className={classNames(
|
||||
// Keep whitespaces?
|
||||
|
||||
@@ -8,9 +8,9 @@ import {
|
||||
} from '@/components/ui/popover';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { IChunk } from '@/interfaces/database/dataset';
|
||||
import { sanitizeHtmlWithImagesAsText } from '@/utils/dom-util';
|
||||
import { CheckedState } from '@radix-ui/react-checkbox';
|
||||
import classNames from 'classnames';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { ChunkTextMode } from '../../constant';
|
||||
import styles from './index.module.less';
|
||||
@@ -102,7 +102,7 @@ const ChunkCard = ({
|
||||
>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: DOMPurify.sanitize(item.content_with_weight),
|
||||
__html: sanitizeHtmlWithImagesAsText(item.content_with_weight),
|
||||
}}
|
||||
className={classNames(styles.contentText, {
|
||||
[styles.contentEllipsis]: textMode === ChunkTextMode.Ellipse,
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
export const scrollToBottom = (element: HTMLElement) => {
|
||||
element.scrollTo(0, element.scrollHeight);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sanitize HTML and render any <img> elements as escaped text strings
|
||||
* instead of loading them as images. Prevents image-based tracking /
|
||||
* data exfiltration via external image URLs and layout disruption, while
|
||||
* keeping the img markup visible to the user as literal text.
|
||||
*
|
||||
* Event-handler XSS (onerror) is already stripped by DOMPurify's default
|
||||
* config; this additionally neutralizes the image element itself.
|
||||
*/
|
||||
export const sanitizeHtmlWithImagesAsText = (html: string): string => {
|
||||
const node = DOMPurify.sanitize(html, { RETURN_DOM: true }) as HTMLElement;
|
||||
node.querySelectorAll('img').forEach((img) => {
|
||||
img.replaceWith(document.createTextNode(img.outerHTML));
|
||||
});
|
||||
return node.innerHTML;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user