React에서는 JSX로 직접 HTML을 작성하지만, 간혹 문자열 형태의 HTML을 렌더링해야 할 때 사용한다.
<div dangerouslySetInnerHTML={{ __html: "<strong>Hello</strong>" }} />
이런 식으로 DOM에 직접 HTML을 삽입한다.
1. XSS (Cross-Site Scripting) 공격 위험
외부 입력값을 그대로 넣으면 악성 스크립트 삽입 가능
이게 그대로 렌더링되면 사용자 브라우저에서 실행됨
const html = `<img src=x onerror="alert('XSS!')" />`
2. 브라우저 보안 정책 우회
dangerouslySetInnerHTML
이라는 이름을 붙여 경고함dangerouslySetInnerHTML
로 삽입된 영역을 다시 diff하지 않기 때문에, 업데이트 누락이나 UI 깨짐이 발생할 수 있음3. HTML injection 가능성
정적이고 신뢰할 수 있는 HTML 문자열만 사용하는 경우
(예: CMS에서 관리자가 입력한 HTML, 마크다운 렌더링 결과 등)
필요한 경우에만 제한적으로 사용, 절대로 사용자 입력 그대로 넘기면 안 됨
1. HTML 파서 라이브러리 사용
import parse from 'html-react-parser';
const safeHTML = '<strong>안녕하세요</strong>';
return <div>{parse(safeHTML)}</div>;
2. sanitize 후 사용
예: DOMPurify
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(userHtml);
return <div dangerouslySetInnerHTML={{ __html: clean }} />;
html-react-parser
, DOMPurify
, 혹은 직접 컴포넌트 구성가능하면 사용을 피하고, 반드시 필요한 경우엔 보안 필터를 거친 후 사용하기
특히 금융/보안/기업 서비스에서는 감사 로그 및 필터링 체계와 함께 쓰는 것이 안전하다.