출처 - https://github.com/jmxx219/CS-Study (opens in a new tab)
XSS와 CSRF
XSS(Cross-Site Scripting)
- 스크립트 언어와 취약한 코드를 공격 대상으로 하여, 공격자가 상대방의 브라우저에 악성 스크립트를 삽입해 의도하지 않은 명령을 실행시키거나 세션 등을 탈취할 수 있는 취약점
- 웹 서버 사용자에 대한 입력값 검증이 미흡할 때 발생할 수 있고, 주로 여러 사용자가 보는 게시판이나 메일 등을 통해 악성 스크립트를 삽입하는 공격 기법
- XSS의 공격 유형으로는
Stored XSS
,Reflected XSS
,DOM-based XSS
가 있음
XSS의 위험성
- 쿠키 정보 및 세션 ID 획득
- 공격자는 XSS에 취약한 페이지 및 게시판에 XSS 공격을 수행함으로써 해당 페이지를 이용하는 사용자의 쿠키 정보나 세션 ID를 획득할 수 있음
- 시스템 관리자 권한 획득
- XSS 취약점이 있는 웹 서버에 다양한 악성 데이터를 포함시킨 후, 사용자의 브라우저가 악성 데이터를 실행하게 할 수 있음
- 공격자는 아직 패치되지 않은 취약점에 대한 공격 코드가 실행되도록 해 사용자의 시스템을 통제할 수 있음
- 악성 코드 다운로드
- 악성 스크립트 자체로 악성 프로그램을 다운로드 할 수는 없음
- 하지만 사용자가 악성 스크립트가 있는 URL을 클릭하도록 유도 해 악성 프로그램을 다운받는 사이트로 리다이렉트(Redirect) 하거나 트로이 목마 프로그램을 다운로드 하도록 유도할 수 있음
- 거짓 페이지 노출
- XSS 공격에 취약한 페이지일 경우,
<script>
태그 뿐만 아니라<img>
와 같은 그림을 표시하는 태그를 사용 해 원래 페이지와는 전혀 관련이 없는 페이지를 표시할 수 있음
- XSS 공격에 취약한 페이지일 경우,
Stored XSS (저장형 크로스사이트 스크립팅)
-
개념
- 공격자의 악성스크립트가 데이터베이스에 저장되고, 이 값을 출력하는 페이지에서 피해가 발생하는 취약점
- 악성 스크립트를 서버에 저장시킨 다음 클라이언트의 요청/응답 과정을 통해 공격하는 방식
- 공격자의 악성스크립트가 서버에 저장되어 불특정 다수를 대상으로 공격에 이용될 수 있어
Reflected XSS
보다 공격 대상의 범위가 훨씬 큼
- 공격자의 악성스크립트가 데이터베이스에 저장되고, 이 값을 출력하는 페이지에서 피해가 발생하는 취약점
-
공격 과정
- 공격자가 게시판에 악성스크립트가 포함된 게시물을 작성하여 게시판 등 사용자가 접근할 수 있는 페이지에 업로드
<script>alert('악성스크립트');</script>
- 이때 사용자가 악성스크립트가 포함된 게시물을 요청하면, 공격자가 삽입한 악성스크립트가 사용자 측에서 동작함
- 공격자가 게시판에 악성스크립트가 포함된 게시물을 작성하여 게시판 등 사용자가 접근할 수 있는 페이지에 업로드
Reflected XSS (반사형 크로스사이트 스크립팅)
-
개념
- 사용자가 요청한 악성스크립트가 사용자측에서 반사되어 동작하는 취약점으로, 공격자의 악성스크립트가 데이터베이스와 같은 저장소에 별도로 저장되지 않고 사용자의 화면에 즉시 출력되면서 피해가 발생함
- 공격자가 악성 스크립트를 클라이언트에게 직접 전달하여 공격하는 방식
- 공격자는 악성스크립트가 포함된 URL을 이메일, 메신저 등을 통해 사용자가 클릭할 수 있도록 유도함
- 사용자가 악성스크립트가 삽입된 URL을 클릭하거나 공격자에 의해 악의적으로 조작된 게시물을 클릭했을 때 사용자의 브라우저에서 악성스크립트가 실행됨
- 사용자가 요청한 악성스크립트가 사용자측에서 반사되어 동작하는 취약점으로, 공격자의 악성스크립트가 데이터베이스와 같은 저장소에 별도로 저장되지 않고 사용자의 화면에 즉시 출력되면서 피해가 발생함
-
공격 과정
- 악의적인 사용자가 보안이 취약한 사이트를 발견했습니다.
- 보안이 취약한 사이트에서 사용자 정보를 빼돌릴 수 있는 스크립트가 담긴 URL을 만들어 일반 사용자에게 스팸 메일로 전달합니다.
- 일반 사용자는 메일을 통해 전달받은 URL 링크를 클릭합니다. 일반 사용자 브라우저에서 보안이 취약한 사이트로 요청을 전달합니다.
- 일반 사용자의 브라우저에서 응답 메시지를 실행하면서 악성 스크립트가 실행됩니다.
- 악성 스크립트를 통해 사용자 정보가 악의적인 사용자에게 전달됩니다.
DOM-based XSS (DOM 기반 크로스사이트 스크립팅)
- 개념
- 공격자의 악성스크립트가 DOM 영역에서 실행됨으로써 서버와의 상호작용 없이 브라우저 자체에서 악성스크립트가 실행되는 취약점
- 피해자의 브라우저가 html 페이지를 분석하여 DOM을 생성할 때 악성 스크립트가 DOM의 일부로 구성되어 생성되는 공격 방식
- 공격자의 악성스크립트가 DOM 영역에서 실행됨으로써 서버와의 상호작용 없이 브라우저 자체에서 악성스크립트가 실행되는 취약점
- 특징
- DOM 영역에 변화가 생기면 브라우저는 서버로 패킷을 보내지 않고 DOM 영역에서 페이지를 변환시키기 때문에 DOM의 일부로 실행되어 브라우저 자체에서 악성스크립트가 실행됨
DOM Based Xss
는 서버와 상호작용 없이 브라우저에서 바로 악성스크립트가 실행되고 공격이 이루어지기 때문에 취약점을 쉽게 발견할 수 없음Stored XSS
와Reflected XSS
는 서버에서 악성스크립트가 실행되고 공격이 이루어지기 때문에 위험 징후를 발견할 수 있음
DOM(Document Object Model)이란?
- HTML, XML 문서의 프로그래밍 interface
- DOM은 문서의 구조화된 표현을 제공하며, 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 도움
XSS의 보안 대책
script 문자 필터링(특수 문자 치환)
특수문자 | < | > | ' | " | ( | ) |
---|---|---|---|---|---|---|
HTML Entity | & lt; | & gt; | & apos; | & quot; | & lpar; | & rpar; |
- XSS 취약점은 공격자가 삽입한 악성스크립트로 인해 발생하기 때문에 입력값 검증을 통해 악성스크립트가 삽입되는 것을 방지해야함
- 또한, 악성스크립트가 입력되어도 동작하지 않도록 출력값을 무효화해야 함
- 입력값 필터링의 경우 데이터베이스에 악성스크립트가 저장되는 것을 원천적으로 차단해야 함
- 악성스크립트를 검증하여 스크립트에 사용되는 특수문자를 HTML Entity로 치환하여 응답하도록 함
String searchWord = request.getParameter("searchWord"); if (searchWord != null) { searchWord = searchWord.replaceAll("<","<"); searchWord = searchWord.replaceAll(">",">"); searchWord = searchWord.replaceAll("(","("); searchWord = searchWord.replaceAll(")",")"); }
- 악성스크립트를 검증하여 스크립트에 사용되는 특수문자를 HTML Entity로 치환하여 응답하도록 함
CSRF(Cross-Site Request Forgery, 사이트 간 요청 위조)
- 웹 보안 취약점의 일종이며, 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(데이터 수정, 삭제, 등록 등)을 특정 웹사이트에 요청하게 하는 공격
- XSS를 이용한 공격이 사용자가 특정 웹사이트를 신용하는 점을 노린 것이라면, CSRF는 특정 웹사이트가 사용자의 웹 브라우저를 신용하는 상태를 노린 것
- 사용자가 웹사이트에 로그인한 상태에서 CSRF 공격 코드가 삽입된 페이지를 열면, 공격 대상이 되는 웹사이트는 위조된 공격 명령이 믿을 수 있는 사용자로부터 발송된 것으로 판단하게 되어 공격에 노출됨
CSRF 공격을 위한 조건
CSRF 공격을 시도하기 위해선 아래와 같은 몇 가지 조건이 필요함
- 사용자가 보안이 취약한 서버로부터 이미 인증을 받은 상태(로그인 등)여야 함
- 쿠키 기반으로 서버 세션 정보를 획득할 수 있어야 함
- 공격자는 서버를 공격하기 위한 요청 방법에 대해 미리 파악하고 있어야 함
CSRF 동작 원리
위와 같은 조건이 만족되면 다음과 같은 과정을 통해 CSRF 공격이 수행됨
- 사용자는 보안이 취약한 서버에 로그인한다.
- 로그인 이후 서버에 저장된 세션 정보를 사용할 수 있는
session ID
가 사용자 브라우저 쿠키에 저장된다. - 공격자는 서버에 인증된 브라우저의 사용자가 악성 스크립트 페이지를 누르도록 유도한다.
- 게시판에 악성 스크립트를 게시글로 작성하여 관리자 혹은 다른 사용자들이 게시글을 클릭하도록 유도
- 메일 등으로 악성 스크립트를 직접 전달하거나, 악성 스크립트가 적힌 페이지 링크를 전달
- 사용자가 악성 스크립트가 작성된 페이지 접속한다.
- 악성 페이지에는 서버를 공격하기 위한 HTTP 요청 스크립트가 존재하기 때문에 쿠키에 저장된
session ID
는 브라우저에 의해 자동으로 요청 헤더에 담겨서 서버로 요청된다.
- 악성 페이지에는 서버를 공격하기 위한 HTTP 요청 스크립트가 존재하기 때문에 쿠키에 저장된
- 서버는 쿠키에 담긴
session ID
를 통해 해당 요청이 인증된 사용자로부터 온 것으로 판단하고 처리한다.
CSRF 공격 예시
- 공격자는 피해자가 접속할 수 있는 게시판에 악성스크립트가 포함된 게시물을 작성한다.
- 예를 들어, 패스워드 변경 페이지에서 패스워드 변경 요청을 보내면 다음과 같은 파라미터를 전송하여 패스워드가 변경된다고 하자.
http://www.example.com/changepassword/modAction.jsp?new_pw1="변경할패스워드"&new_pw2="패스워드확인"&action=change
- 공격자는 자신이 원하는 패스워드로 변경을 유도하는 CSRF 스크립트를 작성하여 게시글을 등록한다.
- 예를 들어, 패스워드 변경 페이지에서 패스워드 변경 요청을 보내면 다음과 같은 파라미터를 전송하여 패스워드가 변경된다고 하자.
- 피해자는 공격자가 등록한 CSRF 스크립트가 삽입된 게시글에 접근하면, 피해자 측에서 패스워드 변경 스크립트가 동작하여 피해자의 패스워드가 변경된다.
- 이후 공격자는 피해자의 패스워드를 알고 있으므로 피해자의 계정을 탈취할 수 있다.
CSRF의 보안 대책
일반적으로 CSRF 공격/방어는 HTTP GET 요청 방식에는 방어 대상에 두지 않고, 쓰기/변경이 가능한 POST, PATCH, DELETE 방식에만 적용하면 됨
Referrer 검증
- 백엔드에서 request의 referrer를 확인하여 domain(ex.
www.naver.com
)이 일치하는 지 검증하는 방법- HTTP 요청 헤더(request header) 정보에서 Referrer 정보를 확인할 수 있고, 보통이라면 호스트(host)와 Referrer 값이 일치하므로 둘을 비교함
- 일반적으로 Referrer 검증만으로 대부분의 CSRF 공격을 방어할 수 있음
- 하지만, 같은 도메인 내의 페이지에 XSS 취약점이 있는 경우 CSRF 공격에 취약해질 수 있음
- domain 단위 검증에서 좀 더 세밀하게 페이지 단위까지 일치하는지 검증을 하면, 도메인 내의 타 페이지에서의 XSS 취약점에 의한 CSFR 공격을 방어 할 수 있음
- 위의 시나리오를 예시로 보면 정상적인 경우, Referrer는 www.example.com의 (opens in a new tab) 패스워드 변경 폼 페이지가 되어야 하지만 비정상적인 요청은 게시판 페이지가 될 것이므로 이를 검증하여 방어할 수 있음
Security Token 사용
- 사용자의 세션에 임의의 난수 값을 저장하고 사용자의 요청 마다 해당 난수 값을 포함 시켜 전송시킨 이후, 백엔드에서 요청이 들어올 때마다 세션에 저장된 토큰 값과 요청 파라미터에 전달되는 토큰 값이 일치하는 지 검증하는 방법
- 이 방법도 같은 도메인 내에 XSS 취약점이 있다면 CSRF 공격에 취약해짐
// 로그인시, 또는 작업화면 요청시 CSRF 토큰을 생성하여 세션에 저장한다.
session.setAttribute("CSRF_TOKEN",UUID.randomUUID().toString());
// 요청 페이지에 CSRF 토큰을 셋팅하여 전송한다
<input type="hidden" name="_csrf" value="${CSRF_TOKEN}" />
// 파라미터로 전달된 csrf 토큰 값
String param = request.getParameter("_csrf");
// 세션에 저장된 토큰 값과 일치 여부 검증
if (request.getSession().getAttribute("CSRF_TOKEN").equals(param)) {
return true;
} else {
response.sendRedirect("/");
return false;
}
기타
- 입력화면 폼 작성 시 (GET) 방식보다는 (POST) 방식을 사용
- 중요 기능에 대해서는 사용자 세션 검증과 더불어 2차, 3차의 추가 인증을 필수적으로 수행하도록 구현함
XSS와 CSRF의 차이점
구분 | XSS | CSRF |
---|---|---|
발생 원인 | 클라이언트가 웹 서버를 신용하여 발생 | 웹 서버가 클라이언트를 신용하여 발생 |
공격 대상 | 클라이언트 | 서버 |
공격 목적 | 쿠키/ 세션 탈취, 악성 사이트로의 이동 등 | 권한 도용, 권한 상승 등 공격자가 원하는 행위 수행 |
공격 행위 | 악의적인 스크립트 작성하여 페이지에 포함시킨 후 실행 유도 | 서버에서 제공하는 기능을 페이지에 포함시킨 후 실행 유도 |
- XSS의 경우 불특정 다수의 클라이언트를 대상으로 공격하지만, CSRF는 서버를 대상으로 공격을 진행함
- 즉 공격자에 의해 삽입된 스크립트가 서버에서 실행되는지, 클라이언트 측에서 실행되는지에 따라 구별할 수 있음
- XSS는 클라이언트 측에서 동작하여 클라이언트의 정보 탈취에 목적이 있지만, CSRF는 공격 대상의 권한을 통해 공격자가 원하는 요청을 보내는 공격이므로 공격자의 의도대로 서버가 동작하게끔 유도함
Ref
- 사이트 간 스크립팅 (opens in a new tab)
- 웹 취약점과 해킹 매커니즘#7 XSS(Cross-Site Scripting) - 개념 (opens in a new tab)
- [Special Report] 웹 취약점과 해킹 매커니즘#9 CSRF(Cross-Site Request Forgery) (opens in a new tab)
- CSRF(Cross-Site Request Forgery) Attack and Defence (opens in a new tab)
- 반사형 XSS(Reflected Cross Site Scripting) 공격과 방어 (opens in a new tab)