innerHTML의 공포에서 벗어나는 법: HTML Sanitizer API가 바꾸는…

대표 이미지

innerHTML의 공포에서 벗어나는 법: HTML Sanitizer API가 바꾸는…

XSS 공격의 주범인 innerHTML을 대체할 브라우저 표준 API의 등장으로, 이제 외부 라이브러리 없이도 안전하고 빠르게 HTML 콘텐츠를 렌더링할 수 있게 되었습니다.

웹 개발자라면 누구나 한 번쯤 innerHTML의 편리함과 위험성 사이에서 갈등해 본 적이 있을 것입니다. 사용자로부터 입력받은 HTML 태그를 화면에 그대로 보여줘야 하는 에디터나 댓글 시스템을 구현할 때, 우리는 항상 ‘교차 사이트 스크립팅(XSS)’이라는 거대한 위협에 노출됩니다. 악의적인 사용자가 <script> 태그나 onerror 속성을 이용해 세션 쿠키를 탈취하거나 페이지를 변조하는 시나리오는 더 이상 이론적인 가설이 아니라 실재하는 위협입니다.

그동안 우리는 이 문제를 해결하기 위해 DOMPurify와 같은 무거운 외부 라이브러리를 도입하거나, 정규표현식을 이용한 불안전한 필터링에 의존해 왔습니다. 하지만 라이브러리 의존성은 번들 크기를 키우고, 업데이트 관리를 필요로 하며, 때로는 브라우저의 최신 파싱 방식과 충돌을 일으키기도 합니다. 이러한 배경 속에서 등장한 HTML Sanitizer API는 브라우저 수준에서 HTML 정화 작업을 수행함으로써 보안성과 성능이라는 두 마리 토끼를 동시에 잡으려는 시도입니다.

브라우저가 직접 검열한다: HTML Sanitizer API의 핵심

HTML Sanitizer API는 신뢰할 수 없는 HTML 문자열을 안전하게 정화하여 Element, ShadowRoot 또는 Document에 삽입할 수 있게 해주는 새로운 웹 표준 API입니다. 기존의 방식이 문자열을 단순히 ‘치환’하는 수준이었다면, 이 API는 브라우저의 실제 HTML 파서를 사용하여 DOM 트리를 분석하고, 미리 정의된 안전한 화이트리스트를 기준으로 위험한 요소와 속성을 제거합니다.

가장 큰 변화는 개발자가 더 이상 ‘무엇을 막을 것인가’를 고민하며 블랙리스트를 작성할 필요가 없다는 점입니다. API는 기본적으로 안전한 태그와 속성만을 허용하며, 필요에 따라 개발자가 허용 범위를 확장하거나 더 엄격하게 제한할 수 있는 유연성을 제공합니다. 이는 보안 설정의 실수로 인해 발생하는 취약점을 획기적으로 줄여줍니다.

기술적 구현과 작동 원리

이 API의 핵심은 Sanitizer 객체와 setHTMLUnsafe()의 안전한 대안으로서 작동하는 메커니즘에 있습니다. 기본적으로 브라우저는 입력된 HTML 문자열을 가상 DOM으로 파싱한 뒤, 각 노드를 순회하며 보안 정책에 위배되는지 확인합니다. 예를 들어 <img src='x' onerror='alert(1)'>라는 입력이 들어오면, API는 img 태그는 허용하지만 onerror라는 이벤트 핸들러 속성은 즉시 제거합니다.

구현 관점에서 보면, 개발자는 다음과 같은 흐름으로 API를 활용하게 됩니다.

  • 기본 정화: 별도의 설정 없이 브라우저 기본 정책을 사용하여 위험 요소를 제거합니다.
  • 사용자 정의 정책: 특정 비즈니스 요구사항에 따라