Dom based XSS 실습 및 대응 방안

실습 환경


claude code를 이용해 생성한 XSS 취약점 테스트용 Flask 서버를 구성한다.


실습


검색 기능을 하는 웹 애플리케이션이다.


URL 입력 창에 [http://192.168.0.100:5000/dom-get?search=<img src=x onerror=”alert(‘DOM based XSS!!’)”>]을 입력하고 접속한다. 그러면 <img> 태그의 자바스크립트가 실행되어 알림창으로 “DOM based XSS!!” 메시지를 출력하게 된다.


취약점이 발생한 이유


클라이언트의 요청으로 서버는 정상적인 페이지를 응답하지만, 클라이언트 측에서 브라우저에 페이지를 렌더링 할 때, 취약한 설정으로 인해서 악성 스크립트가 DOM에 삽입되면서 취약점이 발생한다.


대응 방안


본 실습에서는 createElement(), textContent, createTextNode()를 사용하여 대응할 것이다.

해당 취약점은 innerHTML을 사용하여 사용자 입력 값을 검증 없이 페이지에 렌더링하기 때문에 취약점이 발생한다. 그러므로 createElement(), textContent, createTextNode()를 사용하여 사용자 입력 값을 HTML이 아닌 단순 텍스트로 처리한다.

DOM based XSS가 발생하는 취약한 스크립트는 아래의 이미지와 같다. search 파라미터로 입력받은 값을 searchTerm 변수에 저장하고, innerHTML을 사용해 그대로 출력하고 있다.


아래의 이미지는 시큐어 코딩을 적용한 코드다. createElement()로 <p>, <strong> 태그를 생성하고, textContent와 createTextNode()를 이용해 텍스트만 삽입하여 DOM에 안전하게 추가한다.


시큐어 코딩 후 실습


innerHTML을 사용할 때는 사용자 입력 값이 그대로 포함되어 자바스크립트를 실행할 수 있었다. [http://192.168.0.100:5000/dom-get?search=<img src=x onerror=”alert(‘DOM based XSS!!’)”>] 이 페이로드로 인해 <img> 태그가 삽입된 것을 볼 수 있다.


시큐어 코딩을 적용한 후에는 같은 페이로드를 사용하더라도 <img> 태그가 삽입되는 것이 아닌, 페이로드를 텍스트로 출력하는 것을 볼 수 있다.

Published by