[JavaScript]innerHTML은 안전한가?

OnStar·2022년 4월 9일
0

JavaScript

목록 보기
5/5
post-thumbnail

결론부터 이야기하면, innerHTML은 안전하지 않다.

단, 무작정 innerHTML이 위험하며 절대 사용해서는 안된다는 의미는 아니다.
(eval과 같은 문법과 비교하자면)

MDN 에서도 언급되듯, innerHTML 이 안전하지 않다는 의미는 XSS(Cross-Site Scripting) 공격에 취약하다는 약점을 가지고있기 때문이다.

XSS란?

XSS(Cross-Site Scripting)은 악의적인 목적을 가진 이가 웹사이트에 악성 스크립트를 주입하는 행위를 말한다.

사용자의 입력을 받기 위해 만들어진 input,textarea 창에서 누군가가 스크립트를 작성하고, 그 스크립트가 innerHTML 과 연결되어 파싱을 거친 뒤 코드단에 주입된다면 관리자가 예상하지 못하는 결과가 발생할 수 있다.

스크립트 내용에 따라서 쿠키나 세션 토큰 등의 탈취가 가능해서, 이를 인증이나 세션관리에 사용하고 있는 사이트에 침입하거나 심각한 피해를 입힐 가능성이 있다.

innerHTML과 XSS

문법이 발전됨에 따라 HTML5 부터는 <script> 태그의 삽입의 문제는 해결되었으나 <img src='x' onerror='alert(1)'> 같은 태그의 삽입은 여전히 문제가 되고있다.

따라서 일반 텍스트를 삽입 할 때는 innerHTML 의 사용 대신, 전달 된 내용을 HTML 로 파싱하지 않고 원시 텍스트(raw text)로 삽입하는 Node.textContent 를 사용하는 것이 좋다.

innerHTML의 성능과 대용

앞서 말했듯, innerHTML의 사용은 지양하는 것이 좋으며 일반 텍스트를 삽입 할 때는 Node.textContent 를 사용하는 것이 권장된다. 그렇다면, 더 나아가 innerHTML 대신 사용될 수 있는 문법들과 그에 대한 어떤 기대효과들이 있는지 알아보자.

세부적인 기능과 동작 방식은 다르지만 innerHTML 대신 사용할 수 있는 문법들은 innerText, textContent, insertAdjacentHTML 가 있을 것이다.

innerHTML 의 동작 방식은 element가 기존에 가지고 있던 자식 요소를 파싱하고, 새 값으로 들어온 newDOMString 또한 파싱하여 DocumentFragment 객체를 생성한다. 이렇게 파싱된 객체를 element의 innerHTML에 넣어줌으로써 element의 DOM 요소가 새로운 모습으로 변하게 되는 과정을 가진다. 따라서 파싱을 거치는 innerHTML 은 강력한 만큼 성능상의 약점을 지니는데, 이때 위의 대체적으로 사용할 수 있는 문법들을 사용하면 성능적인 이점을 가져갈 수 있다.

일반 텍스트의 삽입만을 원할 경우에는 innerText, textContent 두 문법을 사용할 수 있지만, textContent는 원시 텍스트를 다루며 성능상의 이점을 더 취하기 때문에 textContent의 사용이 더 권장될 것이다.

HTML 요소를 직접적으로 삽입하고 싶다면, insertAdjacentHTML 을 innerHTML 대신 사용할 수 있는데, 보안상의 이슈가 해결되진 않지만 insertAdjacentHTML은 자식 요소의 파싱 과정이 생략되기 때문에 성능상 훨씬 더 좋은 우위를 차지한다.

0개의 댓글