From ab664e5c9e8f268e8fe029c351049b27dab88bb7 Mon Sep 17 00:00:00 2001 From: Joel Guerra Date: Wed, 4 Sep 2024 18:46:22 +0200 Subject: [PATCH 1/2] fix: Incomplete HTML attribute sanitization --- .gitignore | 2 + packages/main/package.json | 1 - .../SpanDetail/KeyValuesTable.tsx | 2 +- .../Traces/Jaeger-ui/src/utils/jsonMarkup.ts | 107 ++++++++++++++++++ .../Traces/Jaeger-ui/typings/custom.d.ts | 2 +- packages/main/vite.config.ts | 4 +- pnpm-lock.yaml | 60 +--------- 7 files changed, 115 insertions(+), 63 deletions(-) create mode 100644 packages/main/src/components/DataViews/components/Traces/Jaeger-ui/src/utils/jsonMarkup.ts diff --git a/.gitignore b/.gitignore index f5ff4c98..ff184524 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ server .env *.cookie packages/main/.env +codeql-results +codeqldb \ No newline at end of file diff --git a/packages/main/package.json b/packages/main/package.json index 483a8065..dd774131 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -36,7 +36,6 @@ "javascript-time-ago": "^2.5.10", "jquery": "^3.7.1", "jsdom": "24.1.1", - "json-markup": "^1.1.4", "lodash": "^4.17.21", "lru-memoize": "^1.1.0", "memoize-one": "^6.0.0", diff --git a/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx b/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx index 21334b2b..2f14b3f7 100644 --- a/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx +++ b/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/src/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import jsonMarkup from "json-markup"; +import jsonMarkup from "../../utils/jsonMarkup"; import React from 'react'; diff --git a/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/src/utils/jsonMarkup.ts b/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/src/utils/jsonMarkup.ts new file mode 100644 index 00000000..acad51a6 --- /dev/null +++ b/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/src/utils/jsonMarkup.ts @@ -0,0 +1,107 @@ +// this is a fixed version of the json-markup npm package +'use strict' + +const INDENTATION = ' ' + +function createInlineStyle(rules: Record | undefined): string { + let inlineStyle = '' + rules && Object.keys(rules).forEach((property) => { + inlineStyle += `${property}:${rules[property]};` + }) + return inlineStyle +} + +function createStyleApplier(styleFile: Record> | undefined) { + function applyClass(cssClassName: string): string { + return `class="${cssClassName}"` + } + + function applyInlineStyle(cssClassName: string): string { + return `style="${createInlineStyle(styleFile?.['.' + cssClassName])}"` + } + + return styleFile ? applyInlineStyle : applyClass +} + +function determineType(value: any): string { + if (value === null) return 'null' + if (Array.isArray(value)) return 'array' + if (typeof value === 'string' && /^https?:/.test(value)) return 'link' + if (typeof value === 'object' && typeof value.toISOString === 'function') return 'date' + + return typeof value +} + +function escapeHtml(unsafeString: string): string { + return unsafeString + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') +} + +export default function renderJsonMarkup( + jsonObject: any, + styleFile?: Record> | undefined +): string { + let currentIndentation = '' + const applyStyle = createStyleApplier(styleFile) + + function renderList( + items: any[], + startDelimiter: string, + endDelimiter: string, + renderItem: (item: any) => string + ): string { + if (!items.length) return `${startDelimiter} ${endDelimiter}` + + let result = startDelimiter + '\n' + + currentIndentation += INDENTATION + items.forEach((item, index) => { + result += currentIndentation + renderItem(item) + (index < items.length - 1 ? ',' : '') + '\n' + }) + currentIndentation = currentIndentation.slice(0, -INDENTATION.length) + + return result + currentIndentation + endDelimiter + } + + function renderValue(value: any): string { + if (value === undefined) return '' + + switch (determineType(value)) { + case 'boolean': + return `${value}` + + case 'number': + return `${value}` + + case 'date': + return `"${escapeHtml(value.toISOString())}"` + + case 'null': + return `null` + + case 'string': + return `"${escapeHtml(value.replace(/\n/g, '\n' + currentIndentation))}"` + + case 'link': + return `"${escapeHtml(value)}"` + + case 'array': + return renderList(value, '[', ']', renderValue) + + case 'object': + const keys = Object.keys(value).filter((key) => value[key] !== undefined) + + return renderList(keys, '{', '}', (key) => + `"${escapeHtml(key)}": ${renderValue(value[key])}` + ) + } + + return '' + } + + return `
${renderValue(jsonObject)}
` +} \ No newline at end of file diff --git a/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/typings/custom.d.ts b/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/typings/custom.d.ts index 82ca8daa..39184c7b 100644 --- a/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/typings/custom.d.ts +++ b/packages/main/src/components/DataViews/components/Traces/Jaeger-ui/typings/custom.d.ts @@ -30,6 +30,6 @@ declare module 'combokeys' { } declare module 'react-helmet'; -declare module 'json-markup'; +//declare module 'json-markup'; declare module 'react-vis-force'; declare module 'tween-functions'; diff --git a/packages/main/vite.config.ts b/packages/main/vite.config.ts index cbe20de1..2111de4e 100644 --- a/packages/main/vite.config.ts +++ b/packages/main/vite.config.ts @@ -68,10 +68,10 @@ let configOpts = { "@microlink/react-json-view", "date-fns", "nanoid", - "prismjs", "javascript-time-ago", - "json-markup", ], + prinsmJs: ["prismjs"], + dayJs: ["dayjs"], reactDnd: ["react-dnd", "react-dnd-html5-backend"], memoize: [ "memoize-one", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fa6b382f..5424298f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -114,9 +114,6 @@ importers: jsdom: specifier: 24.1.1 version: 24.1.1 - json-markup: - specifier: ^1.1.4 - version: 1.1.4 lodash: specifier: ^4.17.21 version: 4.17.21 @@ -219,7 +216,7 @@ importers: version: 18.3.0 '@typescript-eslint/eslint-plugin': specifier: ^7.17.0 - version: 7.17.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + version: 7.17.0(@typescript-eslint/parser@7.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/parser': specifier: ^7.17.0 version: 7.17.0(eslint@8.57.0)(typescript@5.4.5) @@ -1100,10 +1097,6 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@7.14.1': - resolution: {integrity: sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==} - engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/scope-manager@7.17.0': resolution: {integrity: sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1118,23 +1111,10 @@ packages: typescript: optional: true - '@typescript-eslint/types@7.14.1': - resolution: {integrity: sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==} - engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/types@7.17.0': resolution: {integrity: sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/typescript-estree@7.14.1': - resolution: {integrity: sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/typescript-estree@7.17.0': resolution: {integrity: sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1150,10 +1130,6 @@ packages: peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/visitor-keys@7.14.1': - resolution: {integrity: sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==} - engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/visitor-keys@7.17.0': resolution: {integrity: sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==} engines: {node: ^18.18.0 || >=20.0.0} @@ -2049,9 +2025,6 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - json-markup@1.1.4: - resolution: {integrity: sha512-B5XEjWGMM5txjwBcPMj+J4gsX5u7rzD8m8Iru6h8aKp3tKv/Zzrd2wWOE+clPE+iNJ2dWk4BrlH0S7x2YdF/4g==} - json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -3937,7 +3910,7 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.17.0(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@7.17.0(@typescript-eslint/parser@7.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@eslint-community/regexpp': 4.10.1 '@typescript-eslint/parser': 7.17.0(eslint@8.57.0)(typescript@5.4.5) @@ -3972,11 +3945,6 @@ snapshots: dependencies: '@typescript-eslint/types': 7.17.0 '@typescript-eslint/visitor-keys': 7.17.0 - - '@typescript-eslint/type-utils@7.14.1(eslint@8.57.0)(typescript@5.4.5)': - dependencies: - '@typescript-eslint/types': 7.17.0 - '@typescript-eslint/visitor-keys': 7.17.0 '@typescript-eslint/type-utils@7.17.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: @@ -3990,25 +3958,8 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@7.14.1': {} - '@typescript-eslint/types@7.17.0': {} - '@typescript-eslint/typescript-estree@7.14.1(typescript@5.4.5)': - dependencies: - '@typescript-eslint/types': 7.14.1 - '@typescript-eslint/visitor-keys': 7.14.1 - debug: 4.3.5 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.4 - semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.4.5) - optionalDependencies: - typescript: 5.4.5 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/typescript-estree@7.17.0(typescript@5.4.5)': dependencies: '@typescript-eslint/types': 7.17.0 @@ -4035,11 +3986,6 @@ snapshots: - supports-color - typescript - '@typescript-eslint/visitor-keys@7.14.1': - dependencies: - '@typescript-eslint/types': 7.14.1 - eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@7.17.0': dependencies: '@typescript-eslint/types': 7.17.0 @@ -5085,8 +5031,6 @@ snapshots: json-buffer@3.0.1: {} - json-markup@1.1.4: {} - json-parse-even-better-errors@2.3.1: {} json-schema-traverse@0.4.1: {} From 538f497238c5a7cfc758d9d52237fe3a0788b5ec Mon Sep 17 00:00:00 2001 From: Joel Guerra Date: Thu, 5 Sep 2024 13:41:50 +0200 Subject: [PATCH 2/2] fix: bundle name --- packages/main/vite.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/main/vite.config.ts b/packages/main/vite.config.ts index 2111de4e..dd94dae4 100644 --- a/packages/main/vite.config.ts +++ b/packages/main/vite.config.ts @@ -70,7 +70,7 @@ let configOpts = { "nanoid", "javascript-time-ago", ], - prinsmJs: ["prismjs"], + prismJs: ["prismjs"], dayJs: ["dayjs"], reactDnd: ["react-dnd", "react-dnd-html5-backend"], memoize: [