Status: ✅ Currently Using Declarative Markup
Kami menggunakan pendekatan declarative Svelte markup sebagai solusi utama untuk menampilkan HTML. Ini lebih aman, eksplisit, dan mudah dikelola.
Sebagai gantinya, kami menggunakan struktur data eksplisit dengan markup Svelte:
// ProgramSection.svelte
const timelineItems = [
{
title: 'Minggu 1-2',
subtitle: 'Foundation Setup', // ✅ Eksplisit
description: 'Kenalan dengan...' // ✅ Eksplisit
}
];<!-- TimelineItem.svelte -->
<h3>{title}</h3>
<p>
{#if subtitle}
<strong>{subtitle}</strong>
<br />
{/if}
{description}
</p>Keuntungan:
- ✅ 100% aman (tidak ada HTML string yang perlu di-parse)
- ✅ Eksplisit dan deklaratif (mudah dibaca dan dirawat)
- ✅ Type-safe dengan TypeScript
- ✅ Mudah diubah tanpa risiko XSS
- ✅ UI tetap konsisten
Note: Utility sanitasi sudah tersedia tapi saat ini TIDAK DIGUNAKAN.
Kami juga menyediakan DOMPurify untuk sanitasi HTML jika diperlukan di masa depan.
- Instalasi: DOMPurify sudah terinstall sebagai dependency
- Utility Function:
src/lib/utils/sanitize.ts - Penggunaan: Import dan gunakan di komponen yang menggunakan
{@html}
import { sanitizeHtml } from '$lib/utils/sanitize';
const safeContent = sanitizeHtml(content);<p>{@html safeContent}</p>DOMPurify dikonfigurasi untuk:
- ✅ ALLOWED_TAGS: Hanya tag yang aman (
strong,em,br,p, dll) - ✅ ALLOWED_ATTR: Hanya atribut yang aman (
class,id) - ❌ BLOCKED: Script tags, event handlers, JavaScript URLs
- ❌ BLOCKED: Data attributes yang bisa digunakan untuk XSS
✅ Gunakan sanitasi jika:
- Data dari user input
- Data dari database
- Data dari API eksternal
- Data dari CMS/content management system
✅ Sudah aman tanpa sanitasi jika:
- Data hard-coded di kode (seperti timelineItems di ProgramSection)
- Data statis yang dikontrol developer
- Selalu sanitize konten yang berasal dari user atau sumber eksternal
- Jangan trust data dari sumber eksternal
- Gunakan Content Security Policy (CSP) untuk layer keamanan tambahan
- Review regular dependencies untuk update keamanan
src/lib/components/TimelineItem.svelte✅src/lib/sections/HeroSection.svelte✅
Untuk memastikan sanitasi bekerja dengan baik:
// Test malicious input
const maliciousInput = '<script>alert("XSS")</script><p>Safe content</p>';
const safe = sanitizeHtml(maliciousInput);
// Result: '<p>Safe content</p>' (script tag removed)