BLOG-45 fix: XSS html issue
All checks were successful
Frontend CI / build (push) Successful in 1m3s
All checks were successful
Frontend CI / build (push) Successful in 1m3s
This commit is contained in:
parent
e4807cac7a
commit
06b8c8fa0b
@ -24,6 +24,7 @@
|
|||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.15",
|
||||||
"@tailwindcss/vite": "^4.0.0",
|
"@tailwindcss/vite": "^4.0.0",
|
||||||
"@types/markdown-it": "^14.1.2",
|
"@types/markdown-it": "^14.1.2",
|
||||||
|
"dompurify": "^3.2.6",
|
||||||
"eslint": "^9.18.0",
|
"eslint": "^9.18.0",
|
||||||
"eslint-config-prettier": "^10.0.1",
|
"eslint-config-prettier": "^10.0.1",
|
||||||
"eslint-plugin-svelte": "^3.0.0",
|
"eslint-plugin-svelte": "^3.0.0",
|
||||||
|
16
frontend/pnpm-lock.yaml
generated
16
frontend/pnpm-lock.yaml
generated
@ -38,6 +38,9 @@ importers:
|
|||||||
'@types/markdown-it':
|
'@types/markdown-it':
|
||||||
specifier: ^14.1.2
|
specifier: ^14.1.2
|
||||||
version: 14.1.2
|
version: 14.1.2
|
||||||
|
dompurify:
|
||||||
|
specifier: ^3.2.6
|
||||||
|
version: 3.2.6
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^9.18.0
|
specifier: ^9.18.0
|
||||||
version: 9.31.0(jiti@2.4.2)
|
version: 9.31.0(jiti@2.4.2)
|
||||||
@ -640,6 +643,9 @@ packages:
|
|||||||
'@types/resolve@1.20.2':
|
'@types/resolve@1.20.2':
|
||||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||||
|
|
||||||
|
'@types/trusted-types@2.0.7':
|
||||||
|
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.38.0':
|
'@typescript-eslint/eslint-plugin@8.38.0':
|
||||||
resolution: {integrity: sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==}
|
resolution: {integrity: sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@ -809,6 +815,9 @@ packages:
|
|||||||
devalue@5.1.1:
|
devalue@5.1.1:
|
||||||
resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==}
|
resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==}
|
||||||
|
|
||||||
|
dompurify@3.2.6:
|
||||||
|
resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==}
|
||||||
|
|
||||||
enhanced-resolve@5.18.2:
|
enhanced-resolve@5.18.2:
|
||||||
resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==}
|
resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
@ -1997,6 +2006,9 @@ snapshots:
|
|||||||
|
|
||||||
'@types/resolve@1.20.2': {}
|
'@types/resolve@1.20.2': {}
|
||||||
|
|
||||||
|
'@types/trusted-types@2.0.7':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)':
|
'@typescript-eslint/eslint-plugin@8.38.0(@typescript-eslint/parser@8.38.0(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.31.0(jiti@2.4.2))(typescript@5.8.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/regexpp': 4.12.1
|
'@eslint-community/regexpp': 4.12.1
|
||||||
@ -2175,6 +2187,10 @@ snapshots:
|
|||||||
|
|
||||||
devalue@5.1.1: {}
|
devalue@5.1.1: {}
|
||||||
|
|
||||||
|
dompurify@3.2.6:
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/trusted-types': 2.0.7
|
||||||
|
|
||||||
enhanced-resolve@5.18.2:
|
enhanced-resolve@5.18.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
|
11
frontend/src/lib/common/framework/ui/SafeHtml.svelte
Normal file
11
frontend/src/lib/common/framework/ui/SafeHtml.svelte
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
/* eslint-disable svelte/no-at-html-tags */
|
||||||
|
|
||||||
|
import DOMPurify from 'dompurify';
|
||||||
|
|
||||||
|
const { html }: { html: string } = $props();
|
||||||
|
|
||||||
|
const sanitizedHtml = $derived(DOMPurify.sanitize(html));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{@html sanitizedHtml}
|
@ -3,6 +3,7 @@
|
|||||||
import PostContentHeader from '$lib/post/framework/ui/PostContentHeader.svelte';
|
import PostContentHeader from '$lib/post/framework/ui/PostContentHeader.svelte';
|
||||||
import { getContext, onMount } from 'svelte';
|
import { getContext, onMount } from 'svelte';
|
||||||
import markdownit from 'markdown-it';
|
import markdownit from 'markdown-it';
|
||||||
|
import SafeHtml from '$lib/common/framework/ui/SafeHtml.svelte';
|
||||||
|
|
||||||
const { id }: { id: number } = $props();
|
const { id }: { id: number } = $props();
|
||||||
|
|
||||||
@ -15,12 +16,12 @@
|
|||||||
onMount(() => postBloc.dispatch({ event: PostEventType.PostLoadedEvent, id: id }));
|
onMount(() => postBloc.dispatch({ event: PostEventType.PostLoadedEvent, id: id }));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<article class="prose container pb-10">
|
<article class="container prose pb-10">
|
||||||
{#if state.data}
|
{#if state.data}
|
||||||
<PostContentHeader postInfo={state.data.info} />
|
<PostContentHeader postInfo={state.data.info} />
|
||||||
<div class="max-w-3xl">
|
<div class="max-w-3xl">
|
||||||
<hr />
|
<hr />
|
||||||
{@html parsedContent}
|
<SafeHtml html={parsedContent} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</article>
|
</article>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user