From b6180f69573a253a29d903e393cc9cc7f5d15269 Mon Sep 17 00:00:00 2001 From: Aditya Singh Date: Mon, 2 Jun 2025 12:12:02 +0530 Subject: [PATCH] fix: fix html escape and json string parsing in qb (#8039) Co-authored-by: Aditya Singh --- frontend/src/components/LogDetail/index.tsx | 3 ++- .../src/components/Logs/ListLogView/index.tsx | 4 ++-- .../src/components/Logs/RawLogView/index.tsx | 4 ++-- .../TableView/TableViewActions.tsx | 12 +++++++++--- .../src/container/LogDetailedView/utils.tsx | 18 ++++++++++++++++++ 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/LogDetail/index.tsx b/frontend/src/components/LogDetail/index.tsx index b818823b5a..f6b5da802c 100644 --- a/frontend/src/components/LogDetail/index.tsx +++ b/frontend/src/components/LogDetail/index.tsx @@ -16,6 +16,7 @@ import JSONView from 'container/LogDetailedView/JsonView'; import Overview from 'container/LogDetailedView/Overview'; import { aggregateAttributesResourcesToString, + escapeHtml, removeEscapeCharacters, unescapeString, } from 'container/LogDetailedView/utils'; @@ -118,7 +119,7 @@ function LogDetail({ const htmlBody = useMemo( () => ({ __html: convert.toHtml( - dompurify.sanitize(unescapeString(log?.body || ''), { + dompurify.sanitize(unescapeString(escapeHtml(log?.body || '')), { FORBID_TAGS: [...FORBID_DOM_PURIFY_TAGS], }), ), diff --git a/frontend/src/components/Logs/ListLogView/index.tsx b/frontend/src/components/Logs/ListLogView/index.tsx index b30353696f..8526ce0be8 100644 --- a/frontend/src/components/Logs/ListLogView/index.tsx +++ b/frontend/src/components/Logs/ListLogView/index.tsx @@ -7,7 +7,7 @@ import cx from 'classnames'; import LogDetail from 'components/LogDetail'; import { VIEW_TYPES } from 'components/LogDetail/constants'; import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats'; -import { unescapeString } from 'container/LogDetailedView/utils'; +import { escapeHtml, unescapeString } from 'container/LogDetailedView/utils'; import { FontSize } from 'container/OptionsMenu/types'; import dompurify from 'dompurify'; import { useActiveLog } from 'hooks/logs/useActiveLog'; @@ -58,7 +58,7 @@ function LogGeneralField({ const html = useMemo( () => ({ __html: convert.toHtml( - dompurify.sanitize(unescapeString(fieldValue), { + dompurify.sanitize(unescapeString(escapeHtml(fieldValue)), { FORBID_TAGS: [...FORBID_DOM_PURIFY_TAGS], }), ), diff --git a/frontend/src/components/Logs/RawLogView/index.tsx b/frontend/src/components/Logs/RawLogView/index.tsx index 897dbe98a7..9a305904a6 100644 --- a/frontend/src/components/Logs/RawLogView/index.tsx +++ b/frontend/src/components/Logs/RawLogView/index.tsx @@ -5,7 +5,7 @@ import { DrawerProps } from 'antd'; import LogDetail from 'components/LogDetail'; import { VIEW_TYPES, VIEWS } from 'components/LogDetail/constants'; import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats'; -import { unescapeString } from 'container/LogDetailedView/utils'; +import { escapeHtml, unescapeString } from 'container/LogDetailedView/utils'; import LogsExplorerContext from 'container/LogsExplorerContext'; import dompurify from 'dompurify'; import { useActiveLog } from 'hooks/logs/useActiveLog'; @@ -177,7 +177,7 @@ function RawLogView({ const html = useMemo( () => ({ __html: convert.toHtml( - dompurify.sanitize(unescapeString(text), { + dompurify.sanitize(unescapeString(escapeHtml(text)), { FORBID_TAGS: [...FORBID_DOM_PURIFY_TAGS], }), ), diff --git a/frontend/src/container/LogDetailedView/TableView/TableViewActions.tsx b/frontend/src/container/LogDetailedView/TableView/TableViewActions.tsx index c99426ef54..ad40981a34 100644 --- a/frontend/src/container/LogDetailedView/TableView/TableViewActions.tsx +++ b/frontend/src/container/LogDetailedView/TableView/TableViewActions.tsx @@ -21,8 +21,10 @@ import { FORBID_DOM_PURIFY_TAGS } from 'utils/app'; import { DataType } from '../TableView'; import { + escapeHtml, filterKeyForField, jsonToDataNodes, + parseFieldValue, recursiveParseJSON, removeEscapeCharacters, unescapeString, @@ -85,7 +87,7 @@ export function TableViewActions( record.field === 'body' ? { __html: convert.toHtml( - dompurify.sanitize(unescapeString(record.value), { + dompurify.sanitize(unescapeString(escapeHtml(record.value)), { FORBID_TAGS: [...FORBID_DOM_PURIFY_TAGS], }), ), @@ -155,7 +157,11 @@ export function TableViewActions( ) } - onClick={onClickHandler(OPERATORS['='], fieldFilterKey, fieldData.value)} + onClick={onClickHandler( + OPERATORS['='], + fieldFilterKey, + parseFieldValue(fieldData.value), + )} /> @@ -171,7 +177,7 @@ export function TableViewActions( onClick={onClickHandler( OPERATORS['!='], fieldFilterKey, - fieldData.value, + parseFieldValue(fieldData.value), )} /> diff --git a/frontend/src/container/LogDetailedView/utils.tsx b/frontend/src/container/LogDetailedView/utils.tsx index 05d65259f6..77f765a85e 100644 --- a/frontend/src/container/LogDetailedView/utils.tsx +++ b/frontend/src/container/LogDetailedView/utils.tsx @@ -259,6 +259,24 @@ export const getDataTypes = (value: unknown): DataTypes => { return determineType(value); }; +// prevent html rendering in the value +export const escapeHtml = (unsafe: string): string => + unsafe + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + +// parse field value to remove escaping characters +export const parseFieldValue = (value: string): string => { + try { + return JSON.parse(value); + } catch (error) { + return value; + } +}; + // now we do not want to render colors everywhere like in tooltip and monaco editor hence we remove such codes to make // the log line readable export const removeEscapeCharacters = (str: string): string =>