해당 포스팅은 https://dreamhack.io/lecture/roadmaps/1?obj=8를 참고하여 작성하였으며 공부 목적으로 작성하였습니다.
Cross Site Request Forgery(CSRF)
정의
CSRF(사이트 간 요청 위조)는 임의 이용자의 권한으로 임의 주소에 HTTP 요청을 보낼 수 있는 취약점으로, 이용자의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록, 송금 등)를 특정 웹사이트에 요청하게 만드는 공격이다.
CSRF 공격 방식은 및 과정은 다음과 같다.
- 공격자는 이메일이나 게시판에 CSRF 스크립트가 포함된 게시물을 전송(등록)
- 관리자는 공격자가 등록한 CSRF 스크립트게 포함된 게시물 열람
- 관리자가 CSRF 스크립트가 포함된 게시물을 열람할 시 공격자는 관리자 권한으로 공격자가 원하는 CSRF 스크립트 요청 발생
- 공격자가 원하는 CSRF 스크립트가 실행되어, 관리자 및 사용자의 피해 발생

코드를 예시로 설명하면 더욱 이해하기 쉽다. 아래에 존재하는 예시 코드는 dreamhack에서 제공하는 코드로, CSRF 취약점이 존재하며 송금과 관련된 기능을 수행한다.
# 이용자가 /sendmoney에 접속했을때 아래와 같은 송금 기능을 웹 서비스가 실행함.
@app.route('/sendmoney')
def sendmoney(name):
# 송금을 받는 사람과 금액을 입력받음.
to_user = request.args.get('to')
amount = int(request.args.get('amount'))
# 송금 기능 실행 후, 결과 반환
success_status = send_money(to_user, amount)
# 송금이 성공했을 때,
if success_status:
# 성공 메시지 출력
return "Send success."
# 송금이 실패했을 때,
else:
# 실패 메시지 출력
return "Send fail."
해당 코드는 송금 대상자와 금액을 입력받은 후 별도의 인증 과정이 존재하지 않아 CRSF 공격이 발생할 수 있다.
CSRF 공격 스크립트는 HTML
또는 JavaScript
를 통해 작성할 수 있으며 자주 사용하는 태그는 이미지를 불러오는 img
태그, 웹 페이지에 입력된 양식을 전송하는 form
태그이다. 해당 2개의 태그를 사용해서 HTTP 요청을 보내면 HTTP 헤더인 Cookie에 이용자의 인증 정보가 포함된다.
실제로 위와 같은 코드가 동작하는 서버가 있다고 가정할 때 다음과 같은 코드가 포함된 게시물을 작성하면 CSRF 공격이 수행된다.
<img src="/sendmoney?to=송금받길 원하는 사람&amount=원하는 금액">
그렇다면 XSS와 CSRF의 차이점은 무엇일까?
XSS와 CSRF 취약점 모두 클라이언트를 대상으로 하는 공격이며. 이용자가 악성 스크립트가 포함된 페이지에 접속하도록 유도해야한다.
XSS는 인증 정보인 세션 및 쿠키 탈취가 목적이고 굥격할 사이트의 오리진에서 스크립트를 실행시키는 반면 CSRF는 이용자가 임의 페이지에 HTTP 요청을 보내는 것을 목적으로 하는 공격으로 페이지에 접근한 이용자의 권한으로 웹 서비스의 임의기능을 실행할 수 있는 차이점이 존재한다.
CSRF 방어 방법
CSRF를 방어하는 방법은 크게 Referer 검증, CSRF 토큰 검증, Double Submit Cookie 검증이 있다.
Referer 검증
요청 헤더(request header)에서 Referer 정보를 확인하는 검증 방법으로, 일반적인 경우에 호스트와 Referer 값이 일치하기 때문에 이를 비교하여 검증하는 방식이다. 대부분의 Referer 값에 대한 검증만으로도 방어가 가능하다.
CSRF 토큰 검증
임의의 CSRF 토큰을 생성한 후 세션에 저장한다. 이후 요청하는 페이지에 hidden 타입 input 태그를 이용해 토큰 값을 함께 전달한다. 서버 측에서는 저장된 CSRF 토큰 값과 요청 파라미터에 담긴 토큰 값을 비교하는 검증 방식이다. 이 떄 위조된 페이지는 서버가 발행한 token 값이 일치하지 않아 접근이 불가능하게 된다.
Double Submit Cookie 검증
기본적으로 브라우저에서 Same Origin이 아닐 경우 JavaScript로 쿠키 값을 확인하거나 수정하지 못하는 점을 이용한 검증 방법이다. 실제 동작은 다음과 같다.
- 클라이언트(브라우저)는 GET 요청으로 토큰 값과 시크릿 키값을 서버로부터 받는다
- 클라이언트에서 write 요청 시 헤더에 토큰 값을 주고 쿠키값에 시크릿 키를 부여하여 서버의 중간에서 토큰값을 디코딩한 후 시크릿키가 쿠키값과 일치하는지 체크하여 검증한다.
오류, 잘못된 점 또는 궁금한 점이 있으시다면 댓글 남겨주세요❗
Uploaded by N2T
'Dreamhack > Web hacking' 카테고리의 다른 글
csrf-2 Write-Up (0) | 2023.01.21 |
---|---|
csrf-1 Write-Up (0) | 2023.01.21 |
xss-2 Write-Up💻 (0) | 2023.01.20 |
xss-1 Write-Up💻 (0) | 2023.01.18 |
ClientSide: XSS 🧑🏻💻 (0) | 2023.01.18 |