ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Element.setHTML()이란 ??
    웹 개발 2025. 12. 21. 21:47

    브라우저에서 DOM 요소의 내부 HTML을 바꿀 때 우리는 보통 element.innerHTML = ... 이런 식으로 써왔다.

    그런데 이 방식은 XSS(크로스사이트스크립팅) 공격에 취약하고, 문자열 그대로 HTML을 넣다 보니 예기치 않은 태그나 속성이 들어올 수 있다.


    요즘은 이 문제를 해결하기 위해 실험 단계지만 setHTML()이라는 메서드가 등장했다!

    이 메서드는 HTML 문자열을 파싱하고, XSS나 잘못된 요소는 자동으로 제거한 뒤 요소의 서브트리로 넣어준다는 역할을 한다고 공식 문서가 말한다.


    즉 “HTML 문자열을 안전하게 넣기"를 위한 새로운 메서드이다.

     

    사용법

    기본 문법

    element.setHTML(inputString);
    element.setHTML(inputString, { sanitizer: mySanitizer });
    
    • inputString: 넣고 싶은 HTML 문자열
    • 옵션 객체 sanitizer 속성에는 허용/제거할 태그나 속성을 설정할 수 있는 Sanitizer 객체나 설정이 들어간다.
    • 반환값은 undefined
    • 중요한 건 이건 아직 실험 기능(experimental) 이라는 것, 브라우저 호환성도 체크해야 함

    간단 예제

    <div id="target"></div>
    <script>
      const target = document.getElementById("target");
      const unsafe = `Hello <script>alert("bad")</script> world!`;
      target.setHTML(unsafe);
      // <script> 태그가 제거되고 “Hello  world!” 형태로 들어감
    </script>
    

    원본 문자열에 <script>나 onclick 같은 속성이 있으면 기본 sanitizer 설정이 그걸 제거해준다
    커스텀 sanitizer를 주면 허용할 태그/속성을 직접 지정할 수도 있다.

     

    실사용 예제

    프론트엔드에서 자주 있는 케이스 하나 들어가자: 사용자 입력이나 외부 콘텐츠를 HTML로 출력해야 할 때

    // userContent: 서버에서 가져온 HTML 문자열 (잠재적으로 위험할 수 있음)
    const userContent = await fetch("/api/content").then(res => res.text());
    const container = document.getElementById("content-area");
    
    // unsafe 방식 (innerHTML 사용)
    container.innerHTML = userContent;  // XSS 위험 있음
    
    // 안전한 방식 (setHTML 사용)
    container.setHTML(userContent, { sanitizer: new Sanitizer() });
    

    위 방식으로 바꾸면 userContent에 <script>나 onerror= 같은 공격용 코드가 들어 있어도 기본 sanitizer가 그것을 제거해준다.
    또한 리액트나 뷰 같은 프레임워크 없이 순수 JS에서 외부 HTML을 렌더해야 할 때 유용하다.

     

    주의사항

    • 호환성 문제
      모든 브라우저에서 지원하는 건 아님. 실험 기능이라 “지원된다면” 사용하는 걸 권장한다.
    • sanitizer만 믿어선 안 됨
      서버단에서의 입력 검증이나 출력 인코딩은 여전히 중요해. 외부 입력이 그대로 들어오면 위험해. (한 개발자가 “이건 웹의 오래된 보안 취약점을 고치는 API다”라고 얘기한다)
    • 스타일/스크립트 제거됨
      기본 sanitizer가 <script> 태그를 제거해버림. 만약 정말 특정 스크립트를 넣어야 한다면 커스텀 sanitizer를 설정해야 함.
    • 구조적 제약
      setHTML()은 요소의 컨텍스트상 맞지 않는 태그(예: <col>을 <div> 안에 넣는 등)를 제거할 수 있음
    • 기존 innerHTML 대체 고민 필요
      이미 잘 작동하는 코드가 많다면 바로 바꾸기보다는 단계적으로 검토하고 테스트하는 게 좋음

     

    참고자료

Designed by Tistory.