XSS(Cross Site Scripting)
최근에 과제 테스트를 본 적이 있는데 만족스럽다고 생각하고 제출했지만 당일에 xss 공격으로 뚫려버렸다.
웹 개발자를 희망하면서 이런 취약점도 생각하지 못하고 과제를 제출했다는 게 정말 부끄럽고 내가 많이 부족하다는 것을 다시 깨닫게 되었지만 한편으로는 이번 경험을 계기로 xss에 대해 공부해 보며 한 단계 더 성장할 수 있다는 약간의 기쁜(?) 감정이 들었다.
내가 열심히 만든 과제를 바로 뚫어버린 xss란 녀석은 대체 뭔지 살펴보며 어떻게 대응할 수 있는지도 같이 살펴보자.
xss 공격이란 공격자가 입력한 악성스크립트가 사용자 측에서 응답하는 취약점을 말한다.
공격자가 상대방의 브라우저에 스크립트가 실행되도록 해 사용자의 세션을 가로채거나, 웹 사이트를 변조하거나, 악의적인 콘텐츠를 삽입하거나, 피싱 공격을 진행하는 것을 말한다.
사용자 입력값에 대한 검증이 미흡하거나 출력 시 필터링되지 않을 경우 발생한다.
쿠키 값 또는 세션 등 사용자의 정보를 탈취하거나 피싱 사이트로의 접근 유도 등 사용자에게 직접적인 피해를 줄 수 있다.
XSS 공격 유형
공격자가 삽입한 악성스크립트가 사용자 측에서 어떻게 동작하는지에 따라 크게 세 가지로 분류할 수 있다.
- Stored XSS(저장형 크로스 사이트 스크립팅)
공격자의 악성스크립트가 데이터베이스에 저장되고 이 값을 출력하는 페이지에서 피해가 발생하는 취약점이다.
악성 스크립트가 존재하는 게시글 등을 열람한 사용자들은 쿠키를 탈취당하거나 다른 사이트로 리디렉션 되는 공격을 받게 된다.
위의 그림으로 예를 들어보면 먼저 공격자가 미리 서버에 악성 스크립트를 저장한다.
그다음 사용자가 서버에 데이터를 요청하게 되는데 해당 데이터에는 악성 스크립트가 포함되어 있다.
서버에서는 요청에 대한 응답으로 악성 스크립트가 포함된 데이터를 응답하게 되고, 최종적으로 사용자 PC에서 해당 스크립트가 실행되면서 문제가 발생한다.
이러한 Stored XSS가 위험한 이유는 사용자가 링크를 클릭하도록 유인할 필요 없다는 점이다.
공격자가 서버에 악성 스크립트만 저장하면 사용자가 접속하여 악성 스크립트가 포함된 데이터를 요청하기만을 기다리면 된다.
내가 만든 과제에서 xss 공격을 받았던 이유도 Stored XSS 공격인 것 같았다.
사진과 같이 공격자가 DB에 alert을 실행하는 스크립트를 저장하였다.
내가 만든 과제의 사이트에 접속하면 위의 DB를 먼저 조회하게 되는데, 이때 alert 스크립트도 같이 조회하게 된다.
따라서 사이트에 접속하면 맨 처음에 1이라는 데이터가 alert으로 보이게 되었다.
이런 Stored XSS 공격이 발생하는 이유는 일반적으로 입력 값을 검증하지 않기 때문에 발생한다.
내가 개발한 프로젝트도 입력 값 검증 부분이 정확하지 못했다.
영어 소문자만 저장해야 돼서 정규식을 사용하여 입력 값을 처리했는데 이 부분까지 생각을 못했던 것이 아쉬웠다.
- Reflected XSS(반사형 크로스 사이트 스트립팅)
Reflected XSS 공격은 가장 일반적인 유형의 xss 공격으로 주입된 악성 스크립트가 웹 서버에서 반사되는 공격이다.
주로 이메일 메시지나 다른 웹사이트와 같은 다른 경로를 통해서 악성 스크립트가 사용자에게 전달된다.
위의 그림을 예시로 들어보면 먼저 공격자가 사용자에게 악성 스크립트가 포함된 URL을 전달한다.
그 후 사용자가 해당 링크를 클릭하거나, 특별히 제작된 양식을 서버에 제출할 경우 사전에 포함된 악성 스크립트는 xss에 취약한 웹사이트로 이동하게 된다.
그다음 서버에서 사용자의 브라우저로 응답을 다시 반환(반사)하게 되는데 사용자의 브라우저는 신뢰할 수 있는 서버에서 온 코드이기 때문에 코드를 실행하게 되면서 공격을 당한다.
사용자가 요청한 악성스크립트가 사용자 측에서 반사되어 동작하는 취약점으로 공격자의 악성스크립트가 데이터베이스와 같은 저장소에 별도로 저장되지 않고 사용자의 화면에 즉시 출력되면서 피해가 발생한다.
이러한 Reflected XSS 공격은 주로 검색 결과 또는 입력한 값을 오류 메시지와 함께 보여주는 곳에 악성 스크립트를 삽입하게 되며, 해당 스크립트는 서버가 사용자의 입력 값을 포함해 응답으로 전송할 때 실행된다.
악성 스크립트는 링크를 클릭한 사용자의 쿠키 값을 공격자에게 전송하도록 설정되어 있어 웹사이트에 입력한 모든 정보가 노출된다.
- DOM Based XSS(DOM 기반 크로스사이트 스크립팅)
DOM Based XSS 공격은 공격자의 악성스크립트가 DOM 영역에서 실행됨으로써 서버와의 상호작용 없이 브라우저 자체에서 악성스크립트가 실행되는 취약점이다.
그림을 통해 살펴보면 먼저 공격자가 사용자에게 악성 스크립트가 포함된 URL을 전송한다.
사용자는 해당 URL을 클릭하여 서버로부터 HTML 문서를 전달받게 된다.
사용자의 브라우저는 응답받은 HTML 문서를 읽으면서 필요한 스크립트를 실행하게 되는데 이때 이전에 포함되었던 악성 스크립트가 동작하게 된다.
DOM(Document Object Model, 문서 객체 모델)을 잠깐 알아보면 DOM은 HTML, XML 문서의 프로그래밍 인터페이스이다.
브라우저가 HTML 문서를 읽고 해석한 결과를 DOM 형태로 재구성하여 사용자에게 제공해 주는데 이때 문제가 되는 부분은 자바스크립트와 같은 스크립팅 언어를 이용하여 DOM을 수정할 수 있다는 점이다.
이러한 DOM 영역에 변화가 생기면 브라우저는 서버로 패킷을 보내지 않고 DOM 영역에서 페이지를 변환시킨다.
따라서 DOM의 일부로 실행되기 때문에 브라우저 자체에서 악성스크립트가 실행되면서 취약점을 쉽게 발견하기 어려워진다.
Stored XSS와 Reflected XSS는 서버에서 악성 스크립트의 공격이 이루어지기 때문에 위험 징후를 발견할 수 있지만 DOM Based XSS는 브라우저에서 바로 공격이 이루어지기 때문에 취약점을 쉽게 발견할 수 없다. 따라서 보다 깊은 주의가 필요하다.
XSS 어떻게 예방할 수 있을까?
XSS 취약점은 공격자가 삽입한 악성스크립트로 인해 발생하기 때문에 입력값 검증을 통해 악성스크립트가 삽입되는 것을 방지해야 하며 악성스크립트가 입력되어도 동작하지 않도록 출력값을 무효화해야 한다.
- 입력값 필터링
스크립트에 쓰이는 문자를 의미가 없는 일반 문자로 치환해야 한다.
스크립트에 쓰이는 문자를 탐지하면 escape로 방어하여 문자를 치환하는 것도 한 가지 방법이다.
- X-XSS-Protection 헤더
HTTP 헤더에 X-XSS-Protection 헤더를 추가하여 XSS 공격을 감지할 때 페이지 로드를 중지시킬 수 있다.
- CSP(Content Security Policy)
CSP는 웹 브라우저에서 사용하는 콘텐츠 기반의 보안 정책으로 악성 스크립트를 삽입하는 공격들을 막기 위해 사용된다.
참고 자료
'CS > 보안' 카테고리의 다른 글
[보안] - SQL Injection (1) | 2024.09.16 |
---|