mirror of
https://github.com/R0m1k3/podcastic.git
synced 2026-10-22 06:28:03 +02:00
security: sanitize episode HTML with DOMPurify (XSS)
Episode descriptions came from third-party RSS feeds and were rendered via dangerouslySetInnerHTML without sanitization. Wrap with DOMPurify using a whitelist of safe tags/attrs and an http(s)/mailto-only URI regex. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e2adce33b8
commit
9bf95b4ac9
3 files changed
+6190
-4
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { X, Play, Clock, Calendar, BarChart2 } from 'lucide-react';
|
||||
import { Episode } from '../services/episodeService';
|
||||
|
||||
@@ -109,9 +110,15 @@ export default function EpisodeDetails({ episode, isOpen, onClose, onPlay }: Epi
|
||||
{/* Description */}
|
||||
<div className="space-y-6">
|
||||
<h3 className="text-xl font-display font-black">À propos de cet épisode</h3>
|
||||
<div
|
||||
<div
|
||||
className="prose dark:prose-invert max-w-none text-[var(--text-secondary)] leading-relaxed text-lg"
|
||||
dangerouslySetInnerHTML={{ __html: episode.description }}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: DOMPurify.sanitize(episode.description || '', {
|
||||
ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'b', 'i', 'u', 'a', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'blockquote', 'code', 'pre'],
|
||||
ALLOWED_ATTR: ['href', 'target', 'rel'],
|
||||
ALLOWED_URI_REGEXP: /^(?:https?|mailto):/i,
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in new issue
Block a user