안녕하세요, 개발자 여러분! 웹 애플리케이션을 만들다 보면 사용자 입력을 처리할 때마다 떠오르는 그 익숙한 걱정거리, XSS(Cross-Site Scripting) 공격. 악의적인 스크립트가 HTML에 주입되어 사용자 데이터를 훔치거나 사이트를 망가뜨리는 그 끔찍한 시나리오 말입니다. 오늘은 이런 문제를 간단하고 효과적으로 해결해주는 오픈소스 라이브러리, DOMPurify를 소개할게요. 이 글은 GitHub 리포지토리(https://github.com/cure53/DOMPurify)의 내용을 바탕으로 작성되었으니, 함께 탐구하며 실제로 어떻게 적용할 수 있는지 알아보겠습니다.
DOMPurify는 2014년부터 개발된 JavaScript 라이브러리로, HTML, MathML, SVG 같은 콘텐츠를 안전하게 정화(sanitize)해주는 도구예요. 브라우저의 DOM을 직접 다루며, 초고속으로 작동하면서도 높은 보안성을 자랑하죠. 만약 당신의 프로젝트에서 사용자 입력을 HTML로 렌더링해야 한다면, 이 라이브러리를 빼놓을 수 없어요!
DOMPurify가 왜 특별할까? 주요 기능 탐구
DOMPurify의 매력은 단순함과 강력함의 조화에 있어요. 기본 설정만으로도 안전하게 작동하지만, 필요에 따라 세밀한 커스터마이징이 가능하답니다.
- XSS 방어의 핵심: HTML, SVG, MathML을 필터링해 위험한 태그나 속성을 제거합니다. 예를 들어,
<script>alert('hacked!')</script>같은 코드는 완전히 무해하게 변신하죠. - 브라우저 호환성 최고: Safari 10+, Chrome, Firefox 등 현대 브라우저를 모두 지원해요. 구형 IE(Internet Explorer)에서는 동작하지 않지만, 2.x 브랜치로 보안 업데이트를 받을 수 있어요.
- 훅(Hooks)으로 확장성 UP:
beforeSanitizeElements나uponSanitizeAttribute같은 훅을 통해 커스텀 로직을 추가할 수 있습니다. 예를 들어, 특정 속성을 검사하거나 로그를 남기고 싶을 때 유용하죠. - 서버사이드 지원: Node.js 환경에서도 jsdom 같은 DOM 구현체와 함께 사용 가능. 다만, happy-dom은 XSS 취약점이 있어 피하세요!
- 테스트 철저: 28개 브라우저와 Node.js 버전(v18~v23)에서 자동 테스트를 거칩니다. 안정성에 자신 있어요.
이 기능들 덕분에 jQuery나 Angular 같은 프레임워크와도 잘 어울려요. 데모 사이트(https://cure53.de/purify)에서 직접 테스트해보세요 – 클릭 한 번으로 XSS 공격 시뮬레이션을 볼 수 있어요!
설치: 5분 만에 시작하기
설치는 간단해요. 브라우저나 Node.js 환경에 따라 선택하세요.
브라우저에서
HTML에 스크립트 태그로 불러오면 끝!
<!-- 개발용 (소스맵 포함) -->
<script src="dist/purify.js"></script>
<!-- 프로덕션용 (미니파이드) -->
<script src="dist/purify.min.js"></script>
Node.js에서
npm으로 설치 후, jsdom과 함께 사용:
npm install dompurify jsdom
const { JSDOM } = require('jsdom');
const createDOMPurify = require('dompurify');
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);
// 또는 ES 모듈
import { JSDOM } from 'jsdom';
import DOMPurify from 'dompurify';
const window = new JSDOM('').window;
const purify = DOMPurify(window);
서버사이드 이슈가 걱정되시면 isomorphic-dompurify를 추천해요. 클라이언트/서버 공통으로 동작하죠!
실제 사용 예시: 코드로 배우기
기본 사용법은 한 줄이면 돼요. 더티한 입력을 깨끗하게 정화하는 거죠.
기본 정화
const dirty = '<img src=x onerror=alert(1)//>'; // 악성 코드
const clean = DOMPurify.sanitize(dirty);
console.log(clean); // <img src="x"> (안전하게 변환)
HTML 프로필만 사용
const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });
고급: 훅 추가로 로그 남기기
DOMPurify.addHook('uponSanitizeAttribute', function(currentNode, hookEvent) {
console.log('제거된 속성:', hookEvent.attrName); // 커스텀 로직
});
SVG/MathML 예시
DOMPurify.sanitize('<svg><g/onload=alert(2)//<p>', { USE_PROFILES: { svg: true } }); // <svg><g></g></svg>
이런 식으로 사용자 입력(예: 댓글, 포스트 콘텐츠)을 처리하면 보안이 한층 강화돼요. 더 많은 예시는 GitHub의 /demos 폴더를 확인하세요.
설정 옵션: 보안과 유연성의 균형
DOMPurify는 20개 이상의 옵션으로 세밀한 제어가 가능해요. 하지만 보안을 최우선으로 하세요!
| 옵션 카테고리 | 주요 옵션 | 설명 | 주의점 |
|---|---|---|---|
| 태그/속성 허용 | ALLOWED_TAGS: ['b', 'i'] |
특정 태그만 허용 | 기본값으로 충분한 경우가 많음 |
| URI 안전 | ADD_URI_SAFE_ATTR: ['my-link'] |
URI 속성 추가 | XSS 위험 증가 가능 |
| 반환 타입 | RETURN_DOM: true |
DOM 노드 반환 | 성능 최적화에 유용 |
| 기타 | SAFE_FOR_TEMPLATES: true |
템플릿 문법 제거 | 프로덕션에서 비추천 (취약점 유발) |
예를 들어, ARIA 속성을 막고 싶다면 ALLOW_ARIA_ATTR: false를 설정하세요. 자세한 옵션은 문서를 참고!
'Programming' 카테고리의 다른 글
| Graffle.js: JavaScript 개발자를 위한 간단하고 타입 안전한 GraphQL 클라이언트 (0) | 2025.10.22 |
|---|---|
| PostgreSQL 18 릴리스: 개발자들을 위한 성능 혁명과 새로운 기능 탐구 (0) | 2025.10.22 |
| Node.js 25.0.0 릴리스: 혁신적인 업데이트와 개발자 필수 체크포인트 (0) | 2025.10.22 |
| Rust 개발자의 생산성을 혁신하는 혁명적 도구: Flowistry 완벽 가이드 (0) | 2025.10.19 |
| jsonriver: 스트리밍 JSON 파싱의 혁신, 개발자들을 위한 가벼운 강물 (0) | 2025.10.19 |