CSRF(Cross Site Request Forgery)에 대해

김강욱·2024년 4월 23일

CS정리

목록 보기
1/2
post-thumbnail

🤐 CSRF란?

CSRF는 Cross Site Request Forgery의 줄임말로 사이트 간 요청 위조를 의미합니다.

공격자가 희생자의 권한을 도용하여 특정 웹사이트에 기능을 실행하게 할 수 있기 때문에 반드시 대응책이 필요한 웹 취약점 중 하나입니다.

즉, 사용자의 브라우저가 이미 인증된 상태를 이용하여, 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행동을 하도록 만드는 공격입니다.

예를 들어 공격자가 희생자의 사용자 정보를 도용하여 다수의 방문자가 사용하고 있는 사이트에 광고성 혹은 유해한 게시글을 업로드 하는 것이 가능하게 됩니다. 물론 대형 사이트들은 이와 같은 CSRF에 대응책을 마련하고 있습니다.

CSRF를 통해 공격을 하기 위해서 만족해야할 조건이 있습니다.

1. 희생자가 공격자가 만든 피싱 사이트에 접속을 해야합니다.
2. 희생자가 위조 요청을 보낼 사이트(페이스북, 인스타그램 등등)에 로그인 되어 있어야 합니다.

대부분 사용자들은 본인이 자주 방문하는 사이트에 대해 자동 로그인 기능을 사용하기 때문에 피싱 사이트에 접속했을 시 해당 로그인된 사용자 정보를 도용하여 희생자가 본인의 로그인 정보로 위조 요청을 보낼 사이트에 의도치 않은 기능을 실행시키도록 하는 것입니다.

희생자가 피싱 사이트에 접속하지 않더라도 XSS에 성공한 사이트에서 CSRF 공격을 실행할 수도 있습니다.



🤐 CSRF 과정

1. 희생자가 위조 요청을 보낼 사이트에 로그인 되어있는 상태로 피싱 사이트에 접속합니다.

2. 희생자가 피싱 사이트에 접속하면 피싱 사이트에서 희생자로 가장하여 요청을 보내고 싶은 사이트(자동 로그인된 사이트들)에 요청을 위조해 전송합니다.

3. 위조 요청을 받은 사이트는 해당 요청에 대한 정상적인 응답을 하게 되고 이로 인해 희생자가 의도하지 않은 행동이 실행되도록 유도합니다.


공격 예시

<img src="http://examplesite/user/logout" width="0" height="0">

위는 img 태그를 사용하는 방식으로 CSRF 공격을 한 형태입니다.

웹 브라우저는 img 태그에서 src 속성에 적힌 URL 주소에 HTTP GET 요청을 보내서 이미지 데이터를 받아옵니다.

이 URL이 이미지 파일을 가리킬 필요가 없이 브라우저는 단순히 지정된 URL로 요청을 보내고 서버로부터 어떤 형태의 응답이든 받아들이기 때문에 위의 코드를 통해서 유저를 강제로 로그아웃 시키는 것이 가능하게 됩니다.



🤐 CSRF 대응방법

CSRF에 대응하는 방법은 크게 3가지가 있습니다.

1. CAPTCHA 사용

CAPTCHA는 웹사이트에서 사람이 접근하려고 하는 것인지 봇이 접근하는 것인지 판단하기 위하여 사용되는 튜링 테스트의 일종입니다.

예를 들어, 중요한 폼을 제출할 때 CAPTCHA를 해결해야 하는 단계를 추가함으로써, 사용자가 실제로 해당 폼을 직접 제출하고 있다는 것을 확인할 수 있습니다.

CAPTCHA를 통과해야만 요청이 진행되기 때문에, CSRF로 인한 무단 요청을 막을 수 있고 사용자가 실제로 해당 요청을 의도했는지를 확인할 수 있기 때문에 유용한 방어 방법 중 하나입니다.

출처: https://namu.wiki/w/CAPTCHA

2. Referer 검증법

요청이 들어올 때 request의 header에 담겨있는 referer 값을 확인하여 같은 도메인에서 보낸 요청인지 검증하여 차단하는 방법입니다.

거의 대부분의 경우 이 Referer 검증법으로 공격을 방어할 수 있습니다.

하지만 동일 사이트 내에서 XSS 취약점이 발견된다면 이를 통하여 CSRF 공격을 실행할 수 있다는 점을 유의해야 하며 이는 페이지 단위까지 쪼개어서 도메인 검증을 하는것으로 페이지 간 CSRF 공격을 방어할 수 있습니다.

페이지 단위의 도메인 검증 구현 단계
1. Referer 헤더 확인
클라이언트에서 서버로 요청을 보낼 때, HTTP Referer 헤더에는 해당 요청이 발생한 페이지의 URL이 포함되어 있습니다. 서버는 이 Referer 헤더를 확인하여 요청이 허용된 특정 페이지에서 발생했는지 검증합니다.
2. 요청의 정합성 검증
리퍼러 헤더를 검사하는 것 외에도, 요청이 특정 액션(예: 이메일 변경, 비밀번호 변경 등)과 관련된 유효한 페이지에서만 발생했는지 추가적으로 확인합니다.
3. 안전한 Referer 정책 설정
웹 서버나 웹 어플리케이션에 안전한 Referer 정책을 설정하여, 민감한 요청에 대한 Referer 헤더의 존재 및 정확성을 필수적으로 요구합니다.

3. CSRF Token 사용

사용자의 세션에 임의의 값을 저장하여 모든 요청마다 그 값을 포함하여 전송합니다.

그리고 요청이 들어올 때 마다 백엔드에서 세션에 저장된 값과 요청으로 전송된 값이 일치하는지 검증하여 방어하는 방법입니다. Referer 검증법과 같이 XSS를 통한 CSRF 공격에 취약하다는 특징이 있습니다.

XSS 공격에 약한 이유는 사용자의 브라우저에 악성 스크립트를 심어 CSRF 토큰을 탈취한다면, 공격자가 이 토큰을 사용하여 정당한 요청처럼 위장할 수 있기 때문입니다.


CSRF 토큰 이용 단계
1. CSRF 토큰 생성 및 저장
사용자가 로그인하거나 새 세션을 시작할 때, 서버는 임의의 고유한 토큰을 생성합니다. 이 토큰은 예측 불가능해야 하며, 각 사용자 세션마다 고유해야 합니다. 생성된 토큰은 사용자의 세션에 저장됩니다. 즉, 서버 메모리 내의 세션 저장소나 데이터베이스에서 관리될 수 있습니다.
2. 폼과 AJAX 요청에 토큰 포함
웹 페이지의 모든 폼에는 <input type="hidden" name="csrf_token" value="토큰"> 형식으로 CSRF 토큰을 포함시킵니다. 이렇게 하면 폼을 제출할 때 CSRF 토큰이 자동으로 서버로 전송됩니다. 자바스크립트를 사용하는 비동기 요청(AJAX)에도 헤더나 요청 본문에 CSRF 토큰을 추가합니다. 예를 들어, Axios 또는 jQuery를 사용할 경우 요청 헤더에 토큰을 포함시킬 수 있습니다.
3. 요청 검증(토큰 검증)
서버는 사용자로부터 요청을 받을 때마다 포함된 CSRF 토큰을 세션에 저장된 토큰과 비교합니다. 토큰이 일치하지 않거나 토큰이 없는 경우, 요청은 거부됩니다.


🤐 참고 : HTTP Referer


  • refererhttp 헤더중 하나입니다.
  • HTTP 프로토콜에는 referer 라는 헤더 값이 있는데, 브라우저가 서버로 이 헤더값을 설정해서 보내게 됩니다. 그리고 서버는 referer를 참조함으로써 현재 표시하는 웹페이지가 어떤 웹페이지에서 요청되었는지 알 수 있습니다.
  • 또한 어떤 웹사이트나 웹서버에서 방문자가 왔는지를 파악할 수 있는 기능을 referer를 통해 할 수 있다.
  • 예를 들어, http://www.AAAAA.com 이라는 웹 페이지에 있는 링크를 클릭하여 http://www.BBBBBB.com 으로 이동했을 때 referer는 http://www.AAAAA.com이 된다.
  • 헤더에 담겨 있는 현재 페이지에 요청한 이전 페이지의 uri 정보 정도로 볼 수 있다.

참고 사이트
티베트 모래여우님의 CSRF 블로그 글

profile
TO BE DEVELOPER

0개의 댓글