Secure User Content Display Component
Secure component for displaying user-generated content with XSS prevention and optional HTML sanitization
// components/SecureUserContent.tsx
import DOMPurify from 'isomorphic-dompurify';
import { useMemo } from 'react';
interface SecureUserContentProps {
content: string;
allowHTML?: boolean;
allowedTags?: string[];
}
export function SecureUserContent({
content,
allowHTML = false,
allowedTags = ['b', 'i', 'em', 'strong', 'a', 'p', 'br']
}: SecureUserContentProps) {
// Sanitize HTML if allowed
const sanitized = useMemo(() => {
if (!allowHTML) {
// Default: React automatically escapes content
return null;
}
return DOMPurify.sanitize(content, {
ALLOWED_TAGS: allowedTags,
ALLOWED_ATTR: ['href', 'target', 'rel'],
ALLOW_DATA_ATTR: false,
FORBID_TAGS: ['script', 'iframe', 'object', 'embed'],
FORBID_ATTR: ['onerror', 'onload', 'onclick'],
});
}, [content, allowHTML, allowedTags]);
if (allowHTML && sanitized) {
return (
<div
dangerouslySetInnerHTML={{ __html: sanitized }}
className="user-content"
/>
);
}
// Safe default: React escapes automatically
return <div className="user-content">{content}</div>;
}
// Usage
function UserProfile({ user }: { user: User }) {
return (
<div>
<h1>{user.name}</h1>
{/* Safe - React escapes automatically */}
<SecureUserContent content={user.bio} />
{/* Sanitized HTML if needed */}
<SecureUserContent
content={user.htmlBio}
allowHTML={true}
allowedTags={['p', 'br', 'strong', 'em']}
/>
</div>
);
}