diff --git a/package-lock.json b/package-lock.json index 6275087..c49fefb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,6 +65,7 @@ "react-slick": "0.31.0", "react-theme-switch-animation": "^1.0.0", "recharts": "2.15.2", + "rehype-sanitize": "^6.0.0", "simple-icons": "^16.2.0", "sonner": "2.0.3", "tailwind-merge": "3.2.0", @@ -7141,6 +7142,21 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-sanitize": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", + "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "unist-util-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", @@ -10115,6 +10131,20 @@ "@babel/runtime": "^7.9.2" } }, + "node_modules/rehype-sanitize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz", + "integrity": "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-sanitize": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", diff --git a/package.json b/package.json index 68289c9..f428731 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "react-slick": "0.31.0", "react-theme-switch-animation": "^1.0.0", "recharts": "2.15.2", + "rehype-sanitize": "^6.0.0", "simple-icons": "^16.2.0", "sonner": "2.0.3", "tailwind-merge": "3.2.0", diff --git a/src/app/utils/renderMarkdown.tsx b/src/app/utils/renderMarkdown.tsx index 8c5bebb..7f4c449 100644 --- a/src/app/utils/renderMarkdown.tsx +++ b/src/app/utils/renderMarkdown.tsx @@ -1,4 +1,20 @@ import ReactMarkdown from "react-markdown" +import rehypeSanitize, { defaultSchema } from "rehype-sanitize" + +const sanitizeSchema = { + ...defaultSchema, + attributes: { + ...defaultSchema.attributes, + a: [ + ...(defaultSchema.attributes?.a ?? []), + ], + }, + protocols: { + ...defaultSchema.protocols, + href: ["http", "https", "mailto"], + src: ["http", "https"], + }, +} export default function RenderMarkdownContent({ content, @@ -7,6 +23,7 @@ export default function RenderMarkdownContent({ }) { return (

{children}

, p: ({ children }) =>

{children}

,