innerHTML 이란?
웹 개발에서 사용되는 JavaScript의 속성 중 하나로, 해당 요소의 내부 HTML 콘텐츠를 변경하거나 삽입하는 데 사용된다. 바닐라 자바스크립트에서 innerHTML 을 사용하면 다음과 같은 형태가 된다.
const H1 = document.querySelector('h1')
H1.innerHTML ="안녕하세요!"
사실 이 자체만 본다면, 간편하게 HTML 요소를 브라우저에 표시할 수 있으니까 문제가 없어 보인다. 그럼 왜 문제가 된다는 걸까?
사용하지 말아야 하는 이유
보안 취약점
innerHTML을 사용하면 사용자가 입력한 데이터를 직접 HTML에 삽입할 수 있다. 이렇게 하면 크로스 사이트 스크립팅 (XSS) 공격과 같은 보안 취약점이 발생할 수 있다. 악의적인 사용자가 스크립트를 주입하여 사이트를 공격하거나 사용자의 개인 정보를 탈취할 수 있다.
성능 문제
innerHTML을 사용하면 해당 요소의 내용을 변경할 때마다 브라우저는 내용을 파싱하고 다시 렌더링해야 한다. 이 작업은 성능에 부정적인 영향을 미칠 수 있으며, 대규모 애플리케이션에서는 특히 문제가 될 수 있다.
DOM 구조 파괴
innerHTML을 사용하면 해당 요소의 내용 전체를 대체하므로 요소의 이벤트 핸들러 및 데이터 바인딩과 같은 기존의 DOM 요소와 관련된 작업을 파괴할 수 있다. 무엇보다 데이터를 재사용하는 것이 아니라 처음 부터 다시 렌더링하는 것이므로 앞서 언급한 성능문제로 이어질 수 있다.
대체방법은?
대신에, DOM 조작을 수행할 때는 다음과 같은 방법을 고려해볼 수 있다.
우선, document.createElement() 를 사용하여 새 요소를 생성하고 appendChild() 또는 insertBefore()와 같은 메서드를 사용하여 요소를 DOM에 삽입한다. |
이렇게 하면, innerHTML로 삽입한 DOM 요소를 모두 재렌더링 할 필요 없이 필요한 DOM 요소만 따로 추가할 수 있으므로 성능상 이슈를 최소화할 수 있다.
두 번째는
insertAdjacentHTML() 을 사용하여, DOM 요소를 제거하지 않고 추가하는 방식을 활용한다. |
이 메소드는 DOM 요소를 모두 재렌더링하는 innerHTML 과는 다르게 기존 DOM 요소를 유지한 채 특정 위치에 추가하고자 하는 DOM 요소를 삽입하는 방식으로 작동한다.
그리고,
textContent 또는 createTextNode()를 사용하여 텍스트 내용을 변경토록 한다. |
innerHTML 의 가장 큰 단점은 사용자가 입력한 HTML 요소가 스크립트에 반영될 수 있다는 점이다. 만일 악의적인 사용자가 <script> 무시무시한 악의적 코드 </script> 를 입력하고, 그 사이에 악성코드가 삽입한 페이지로 강제 이동시키는 코드 등의 악의적인 스크립트 코드를 작성한다면, 이 만큼 공포스러운 경우는 없을 것이다.
참고할 점은 HTML5 에서는 innerHTML 과 함께 삽입된 <script> 태그가 실행되지 않도록 지정하므로 스크립트 태그를 사이에 추가해서 생기는 문제는 크게 걱정할 필요는 없다. 그런데 만일 <img onerror="악의적인 코드"> 방식이라면 어떻게 될까? 스크립트 태그는 HTML5 에서 보호해주지만, img 태그 등과 같이 error 이벤트를 실행시킬 수 있는 태그는 그렇지 못하다. 그러니 매우 위험하다. |
이러한 점에서, textContent 의 경우에는 사용자가 입력한 값을 모두 Text 노드로 취급하기 때문에 그런 위험을 줄일 수 있다.
나가는 길
innerHTML 의 문제 중 가장 큰 문제는 보안 상의 위험이 언제나 존재한다는 사실이다. 그래서인지 리액트에서는 innerHTML 을 사용하려고 하면, 코드명 자체에 위험하다라고 경고문구를 달아두었다.
간단한 코드 작성 시(보안상 위험이 없는) innerHTML 을 사용해 왔지만, innerHTML 뿐만 아니라 서버로 데이터를 전송할 때에도 악의적인 코드가 담긴 HTML 코드를 담아서 보낸다거나, 데이터베이스의 특성을 활용해서 저장 시 악의적인 스크립트가 저장되게 하고, 이를 get 요청으로 받아왔을 때 악의적인 스크립트가 실행되게 하는 방식 등의 다방면으로 악용이 가능하다는 생각이 든다.
추가적으로, 자바스크립트는 브라우저 상에서 사용자 누구나 접근이 가능한 만큼 전역변수의 사용이 가져오는 스크립트 조작 등의 위험도 있음을 알고 있다. 이러한 사항들을 모두 고려한 코드 작성이 중요함을 많이 느낀다.
참고자료
https://developer.mozilla.org/ko/docs/Web/API/Element/innerHTML
유데미 - 자바스크립트 초급-고급 과정 강의
'자바스크립트' 카테고리의 다른 글
[javascript] async ~ await 에 대한 정리 (0) | 2023.11.13 |
---|---|
[javascript] reduce 메서드의 다양한 활용 (0) | 2023.11.10 |
[JS] Map 에 대한 정리 (0) | 2023.09.27 |
[JS] 자바스크립트의 렌더링 블록과 방지방법에 대한 정리(defer 와 async) (0) | 2023.09.23 |
[js] 클로저에 대한 정리 (2) | 2023.09.21 |