From 32c9a2f2a09f0a3a2638f0fd76b2f551d491d4fd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 15 Dec 2022 02:26:55 +0000 Subject: [PATCH] [Table Visualization][BUG] Fix Url content display (#2918) Currently, the new table can not format Url. If we set to use URL format in index pattern field, table will display it as string. In this PR, we switch the format from string to html. To make html understandable by react as a DOM element, we use dangerouslySetInnerHTML to transform it. For the security, since the content is not from random input but fetched from stored data, we should be safe as long as data is not messed. To provide more security protection, we also add dompurify package to sanitize the html content. Issue Resolved: https://github.com/opensearch-project/OpenSearch-Dashboards/issues/2905 Signed-off-by: Anan Zhuang Signed-off-by: Anan Zhuang (cherry picked from commit b16ee648bb4fde8abe13bad3f36b60074ab38cad) Signed-off-by: github-actions[bot] # Conflicts: # CHANGELOG.md --- package.json | 2 ++ .../public/components/table_vis_component.tsx | 16 +++++++++++++--- yarn.lock | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index e61b513ded6b..6c5085a1b14d 100644 --- a/package.json +++ b/package.json @@ -264,6 +264,7 @@ "@types/dedent": "^0.7.0", "@types/deep-freeze-strict": "^1.1.0", "@types/delete-empty": "^2.0.0", + "@types/dompurify": "^2.3.3", "@types/elasticsearch": "^5.0.33", "@types/enzyme": "^3.10.7", "@types/eslint": "^6.1.3", @@ -352,6 +353,7 @@ "d3-cloud": "1.2.5", "dedent": "^0.7.0", "delete-empty": "^2.0.0", + "dompurify": "^2.4.1", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", "enzyme-to-json": "^3.5.0", diff --git a/src/plugins/vis_type_table_new/public/components/table_vis_component.tsx b/src/plugins/vis_type_table_new/public/components/table_vis_component.tsx index 4a25395703b0..cbd0331b419c 100644 --- a/src/plugins/vis_type_table_new/public/components/table_vis_component.tsx +++ b/src/plugins/vis_type_table_new/public/components/table_vis_component.tsx @@ -5,6 +5,7 @@ import React, { useCallback, useMemo } from 'react'; import { orderBy } from 'lodash'; +import dompurify from 'dompurify'; import { EuiDataGridProps, EuiDataGrid, EuiDataGridSorting, EuiTitle } from '@elastic/eui'; import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; @@ -50,9 +51,18 @@ export const TableVisComponent = ({ const rawContent = sortedRows[rowIndex][columnId]; const colIndex = columns.findIndex((col) => col.id === columnId); const column = columns[colIndex]; - // use formatter to format raw content - // this can format date and percentage data - const formattedContent = column.formatter.convert(rawContent, 'text'); + const htmlContent = column.formatter.convert(rawContent, 'html'); + const formattedContent = ( + /* + * Justification for dangerouslySetInnerHTML: + * This is one of the visualizations which makes use of the HTML field formatters. + * Since these formatters produce raw HTML, this visualization needs to be able to render them as-is, relying + * on the field formatter to only produce safe HTML. + * `htmlContent` is created by converting raw data via HTML field formatter, so we need to make sure this value never contains + * any unsafe HTML (e.g. by bypassing the field formatter). + */ +
// eslint-disable-line react/no-danger + ); return sortedRows.hasOwnProperty(rowIndex) ? formattedContent || null : null; }) as EuiDataGridProps['renderCellValue']; }, [sortedRows, columns]); diff --git a/yarn.lock b/yarn.lock index bdb2bcfa97c6..fc96722de98b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3004,6 +3004,13 @@ resolved "https://registry.yarnpkg.com/@types/delete-empty/-/delete-empty-2.0.0.tgz#1647ae9e68f708a6ba778531af667ec55bc61964" integrity sha512-sq+kwx8zA9BSugT9N+Jr8/uWjbHMZ+N/meJEzRyT3gmLq/WMtx/iSIpvdpmBUi/cvXl6Kzpvve8G2ESkabFwmg== +"@types/dompurify@^2.3.3": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.4.0.tgz#fd9706392a88e0e0e6d367f3588482d817df0ab9" + integrity sha512-IDBwO5IZhrKvHFUl+clZxgf3hn2b/lU6H1KaBShPkQyGJUQ0xwebezIPSuiyGwfz1UzJWQl4M7BDxtHtCCPlTg== + dependencies: + "@types/trusted-types" "*" + "@types/duplexify@^3.6.0": version "3.6.1" resolved "https://registry.yarnpkg.com/@types/duplexify/-/duplexify-3.6.1.tgz#5685721cf7dc4a21b6f0e8a8efbec6b4d2fbafad" @@ -3800,6 +3807,11 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40" integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg== +"@types/trusted-types@*": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" + integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== + "@types/type-detect@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/type-detect/-/type-detect-4.0.1.tgz#3b0f5ac82ea630090cbf57c57a1bf5a63a29b9b6" @@ -7364,6 +7376,11 @@ domhandler@^4.0, domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.2.2, domhan dependencies: domelementtype "^2.2.0" +dompurify@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.1.tgz#f9cb1a275fde9af6f2d0a2644ef648dd6847b631" + integrity sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA== + domutils@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"