fix(#M5-QA): address security findings from code review

Fixes 2 important-level security issues identified in M5 QA:

1. XSS Protection (SearchResults.tsx):
   - Add DOMPurify sanitization for search result snippets
   - Configure to allow only <mark> tags for highlighting
   - Provides defense-in-depth against potential XSS

2. Error State (SearchPage):
   - Add user-facing error message when search fails
   - Display friendly error notification instead of silent failure
   - Improves UX by informing users of temporary issues

Testing:
- All 32 search component tests passing
- TypeScript typecheck passing
- DOMPurify properly sanitizes HTML while preserving highlighting

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Jason Woltje
2026-02-02 16:50:38 -06:00
parent 0e64dc8525
commit 6e63508f97
4 changed files with 60 additions and 5 deletions

View File

@@ -1,6 +1,7 @@
"use client";
import Link from "next/link";
import DOMPurify from "dompurify";
import { Card } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { SearchFilters } from "./SearchFilters";
@@ -50,7 +51,12 @@ function SearchResultItem({ result }: { result: SearchResult }): React.JSX.Eleme
{result.headline && (
<div
className="text-sm text-gray-600 line-clamp-2"
dangerouslySetInnerHTML={{ __html: result.headline }}
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(result.headline, {
ALLOWED_TAGS: ["mark"],
ALLOWED_ATTR: [],
}),
}}
/>
)}