diff --git a/marketplace-ui/package-lock.json b/marketplace-ui/package-lock.json index 261d70c4..786b84c0 100644 --- a/marketplace-ui/package-lock.json +++ b/marketplace-ui/package-lock.json @@ -24,6 +24,7 @@ "@popperjs/core": "^2.11.8", "bootstrap": "^5.3.3", "bootstrap-icons": "^1.11.3", + "dompurify": "^3.2.3", "emoji-toolkit": "^9.0.0", "jwt-decode": "^4.0.0", "karma-viewport": "^1.0.9", @@ -5300,6 +5301,13 @@ "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", "dev": true }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/wrap-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", @@ -7193,6 +7201,15 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.3.tgz", + "integrity": "sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/domutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", diff --git a/marketplace-ui/package.json b/marketplace-ui/package.json index d53ea255..a793dce4 100644 --- a/marketplace-ui/package.json +++ b/marketplace-ui/package.json @@ -26,6 +26,7 @@ "@popperjs/core": "^2.11.8", "bootstrap": "^5.3.3", "bootstrap-icons": "^1.11.3", + "dompurify": "^3.2.3", "emoji-toolkit": "^9.0.0", "jwt-decode": "^4.0.0", "karma-viewport": "^1.0.9", diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.ts b/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.ts index af53a11c..f36f2755 100644 --- a/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.ts +++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.ts @@ -6,7 +6,6 @@ import { Component, ElementRef, HostListener, - SecurityContext, Signal, WritableSignal, computed, @@ -54,6 +53,7 @@ import { DisplayValue } from '../../../shared/models/display-value.model'; import { CookieService } from 'ngx-cookie-service'; import { ROUTER } from '../../../shared/constants/router.constant'; import { SafeHtml, Title, DomSanitizer } from '@angular/platform-browser'; +import DOMPurify from 'dompurify'; import { API_URI } from '../../../shared/constants/api.constant'; import { EmptyProductDetailPipe } from '../../../shared/pipes/empty-product-detail.pipe'; import { LoadingSpinnerComponent } from '../../../shared/components/loading-spinner/loading-spinner.component'; @@ -462,7 +462,7 @@ export class ProductDetailComponent { md.use(MarkdownItGitHubAlerts); md.use(full); // Add emoji support const result = md.render(value); - const safeContent = this.sanitizer.sanitize(SecurityContext.HTML, result); + const safeContent = DOMPurify.sanitize(result); return safeContent ? this.sanitizer.bypassSecurityTrustHtml(safeContent) : ''; diff --git a/marketplace-ui/src/app/modules/release-preview/release-preview.component.ts b/marketplace-ui/src/app/modules/release-preview/release-preview.component.ts index 70f6387c..25231068 100644 --- a/marketplace-ui/src/app/modules/release-preview/release-preview.component.ts +++ b/marketplace-ui/src/app/modules/release-preview/release-preview.component.ts @@ -5,8 +5,7 @@ import { Signal, WritableSignal, computed, - signal, - SecurityContext + signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { CommonModule } from '@angular/common'; @@ -24,6 +23,7 @@ import MarkdownIt from 'markdown-it'; import { full } from 'markdown-it-emoji'; import { DisplayValue } from '../../shared/models/display-value.model'; import { MultilingualismPipe } from '../../shared/pipes/multilingualism.pipe'; +import DOMPurify from 'dompurify'; const DEFAULT_ACTIVE_TAB = 'description'; @Component({ @@ -131,8 +131,7 @@ export class ReleasePreviewComponent { const md = MarkdownIt(); md.use(full); const result = md.render(value); - const safeContent = this.sanitizer.sanitize(SecurityContext.HTML, result); - + const safeContent = DOMPurify.sanitize(result); return safeContent ? this.sanitizer.bypassSecurityTrustHtml(safeContent) : '';