From ce9fb78a8fe59a99f361861d29193c7ebd90aae2 Mon Sep 17 00:00:00 2001 From: andres Date: Mon, 22 Apr 2024 01:21:11 +0200 Subject: [PATCH] feat: sanitize html when parsing rss feed --- package.json | 2 ++ pnpm-lock.yaml | 23 +++++++++++++++++++++++ src/services/rss-parser/rss-parser.ts | 7 +++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9c2ce8a..81af209 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@tanstack/react-query": "^5.29.2", "@tanstack/react-query-persist-client": "^5.29.2", "clsx": "^2.1.0", + "dompurify": "^3.1.0", "idb-keyval": "^6.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -22,6 +23,7 @@ }, "devDependencies": { "@tailwindcss/typography": "^0.5.12", + "@types/dompurify": "^3.0.5", "@types/react": "^18.2.66", "@types/react-dom": "^18.2.22", "@typescript-eslint/eslint-plugin": "^7.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3e5f0d6..32f1ce6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: clsx: specifier: ^2.1.0 version: 2.1.0 + dompurify: + specifier: ^3.1.0 + version: 3.1.0 idb-keyval: specifier: ^6.2.1 version: 6.2.1 @@ -36,6 +39,9 @@ importers: '@tailwindcss/typography': specifier: ^0.5.12 version: 0.5.12(tailwindcss@3.4.3) + '@types/dompurify': + specifier: ^3.0.5 + version: 3.0.5 '@types/react': specifier: ^18.2.66 version: 18.2.79 @@ -482,6 +488,9 @@ packages: peerDependencies: react: ^18.0.0 + '@types/dompurify@3.0.5': + resolution: {integrity: sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==} + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -500,6 +509,9 @@ packages: '@types/semver@7.5.8': resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@typescript-eslint/eslint-plugin@7.7.0': resolution: {integrity: sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==} engines: {node: ^18.18.0 || >=20.0.0} @@ -716,6 +728,9 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dompurify@3.1.0: + resolution: {integrity: sha512-yoU4rhgPKCo+p5UrWWWNKiIq+ToGqmVVhk0PmMYBK4kRsR3/qhemNFL8f6CFmBd4gMwm3F4T7HBoydP5uY07fA==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -1724,6 +1739,10 @@ snapshots: '@tanstack/query-core': 5.29.0 react: 18.2.0 + '@types/dompurify@3.0.5': + dependencies: + '@types/trusted-types': 2.0.7 + '@types/estree@1.0.5': {} '@types/json-schema@7.0.15': {} @@ -1741,6 +1760,8 @@ snapshots: '@types/semver@7.5.8': {} + '@types/trusted-types@2.0.7': {} + '@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@eslint-community/regexpp': 4.10.0 @@ -1969,6 +1990,8 @@ snapshots: dependencies: esutils: 2.0.3 + dompurify@3.1.0: {} + eastasianwidth@0.2.0: {} electron-to-chromium@1.4.740: {} diff --git a/src/services/rss-parser/rss-parser.ts b/src/services/rss-parser/rss-parser.ts index 7acb01f..f1c3273 100644 --- a/src/services/rss-parser/rss-parser.ts +++ b/src/services/rss-parser/rss-parser.ts @@ -1,4 +1,5 @@ import { RssEpisode, RssPodcast } from "./rss-parser.types"; +import DOMPurify from "dompurify"; export class RssParser { public static parse(rss: string): RssPodcast { @@ -66,8 +67,10 @@ export class RssParser { } public static getElementInnerHtml(element: Element | null, tagName: string) { - return this.cleanCDATA( - this.getElementByTagName(element, tagName)?.innerHTML ?? "", + return DOMPurify.sanitize( + this.cleanCDATA( + this.getElementByTagName(element, tagName)?.innerHTML ?? "", + ), ); }