Stored XSS 취약점에 대해 알아보기 앞서 XSS(Cross Site Scripting)취약점에 대해 간략하게 살펴보겠습니다.

XSS ( Cross Site Scripting ) ?

웹 사이트 관리자가 아닌 이가 웹 페이지에 클라이언트 측에서 실행될 수 있는 악성 스크립트를 삽입할 수 있는 취약점

 

Stored XSS ?

공격자가 서버에서 제공되는 게시판, 방명록, 사용자 프로필 등에 악의적인 스크립트를 작성하여 저장한 후 사용자가 게시물, 방명록 등을 확인하면 스크립트가 사용자에게 전달되어 실행되는 취약점

공격자가 작성한 악성 스크립트가 서버에 저장되어 사용된다는 특징이 있다.

 

DVWA 환경에서 Stored XSS 실습

실습환경 구성

우선 본 실습에 앞서 실습 환경의 경우 리눅스 환경에서 DVWA 환경을 구축한 후 가장 취약한 환경인 Low 레벨 환경에서 실습을 진행하였습니다.

Stored XSS 취약점 실습 탭

Stored XSS 취약점 실습을 위해 해당 탭으로 들어온 모습이다.

일반적인 방명록 기능이 있는 것을 확인할 수 있다.

Message 입력란에 클라이언트 측에서 실행될 수 있는 스크립트 작성

방명록 기능을 이용하여 Message 입력란에 클라이언트 측에서 실행될 수 있는 스크립트(사진에서는 쿠키 정보를 알림으로 알려주는 스크립트)를 입력하여 방명록을 작성하였다.

작성 된 방명록을 확인한 모습

방명록 기능을 이용하여 클라이언트 측에서 실행될 수 있는 스크립트를 삽입하여 서버에 저장한 후 방명록을 확인하는 순간 삽입된 스크립트가 실행되어 쿠키 정보가 보여지는 모습을 사진과 같이 확인할 수 있다.

수 차례 Stored XSS 탭에 들어가 작성된 방명록을 확인

이후에도 스크립트가 삽입된 방명록을 삭제하지 않고, 반복적으로 방명록이 작성된 페이지를 방문할 때마다 스크립트가 실행되는 것을 확인할 수 있었다.

Name 입력란에 스크립트 작성 시도

다음으로 이전에 Message 입력란에 스크립트를 작성하여 실습한 것을 삭제하고 Name 입력란에도 같은 방법으로 스크립트를 삽입하여 XSS 실습을 해보기 위해 스크립트를 작성하는 모습이다.

하지만 이전에 Message 입력란에서 잘 작성 되었던 것과 다르게 Name 입력란에서는 글자 수 제한이 걸려있어 일정 글자 수 이상 문자를 입력할 수 없었다.

Name 폼이 구현된 태그를 찾아 개발자 옵션으로 확인한 것

이를 해결하기 위해 개발자 옵션에서 Name 입력 폼이 구현된 태그를 찾아보았다. 그곳에서 최대로 입력될 수 있는 글자 수는 10자로 제한되어 있는 것을 확인할 수 있었고 이를 해제하기 위해 maxlength 속성을 제거하여 글자 수 제한을 해제하였다.

Name 입력란에 클라이언트 측에서 실행될 수 있는 스크립트 삽입

글자 수 제한을 해제한 후 이전과 같이 Name 입력란에 클라이언트 측에서 실행될 수 있는 스크립트를 삽입하여 방명록을 작성하였다.

Name 입력란에 클라이언트 측에서 실행될 수 있는 스크립트를 삽입하여 방명록을 작성한 후  방명록을 확인한 결과

방명록이 작성된 웹 페이지를 확인한 결과 스크립트가 실행되어 알림으로 쿠키 정보를 알려주는 모습을 사진과 같이 확인할 수 있었다.

 

XSS 대응 방안

HTML Entity 형태로 태그 문자를 치환

  • 태그 사용이 필요 없을 경우 태그 문자(<,>)는 HTML Entity 형태로 치환하여 입력된 태그 문자는 문자열로만 인식되도록 구현한다.

화이트리스트 방식으로 태그 제한

  • 부득이하게 태그 사용이 반드시 필요할 경우에는 위 사진과 같이 필요한 태그(예시는 <p>태그)만 사용할 수 있도록 구현한다. => 위 예시는 화이트리스트 방식
  • 아래 사진은 블랙리스트 방식으로 <script> 태그가 입력될 경우 공백으로 치환되도록 구현한 것이다.
  • 화이트리스트 방식이 좀 더 보안적인 측면에서 우수하지만 블랙리스트 방식에 비해 사용성이 떨어질 수 있기 때문에 다방면으로 고려하여 구현해야 한다.

블랙리스트 방식으로 태그 제한
입력 글자 수 제한

  • XSS 취약점은 <script>alert(1)</script>와 같이 사용하려면 최소 글자 수가 10자 이상을 작성해야 한다. 그렇기 때문에 불필요하게 입력 문자 수가 길 필요가 없는 입력 필드는 위 사진과 같이 입력될 수 있는 길이를 제한하여야 한다.
  • 하지만 이때 위 사진과 같이 클라이언트 측에서만 입력 문자 길이를 검증할 경우 maxlength 속성을 삭제하여 글자 수 제한을 우회할 수 있기 때문에 아래 사진과 같이 데이터베이스에서도 길이 제한을 적용해야 한다.

데이터베이스에서 입력 필드 길이 제한

  • 보안 라이브러리(AntiXSS, OWASP 등)을 사용하여 개발한다.