본문 바로가기
💻Information Security

CSRF(Cross Site Request Forgery)이란?

by Prof. Panda 2024. 1. 21.

Nate Grant on Unsplash

CSRF 정의와 XSS와 차이

CSRF는 "Cross Site Request Forgery"의 약자로, XSS와 마찬가지로 'Cross-Stie'가 들어갑니다. 따라서 헷갈리기 쉽지만 XSS는 스크립트가 실행되는 것이고, CSRF는 사용자가 의도하지 않은 요청을 보내도록 하는 것으로 명백한 차이가 있습니다. 둘 다 공격 대상은 사용자인 클라이언트 측이지만, 실행이 되는 위치는 다릅니다. XSS의 경우 스크립트가 브라우저에서 해석되어서 실행되는 것이므로 클라이언트 쪽 브라우저입니다. 하지만, CSRF의 경우 요청을 서버로 전송하게 되기 때문에 실행은 서버에서 되는 것이라고 비교해볼 수 있겠습니다. 

취약점이 위치할 수 있는 장소

CSRF는 피해자가 의도하지 않은 '요청을 전송'하는 것이므로 요청이 전송되는 곳에 있을 수 있습니다. 특히, 그 요청을 조작할 수 있거나 인증이 부족한 경우에도 CSRF 취약점이 존재할 수 있습니다.

  • 서버 내에서 '요청'을 전송하는 위치가 있다.
  • 요청을 임의로 조작할 수 있다.
  • 요청에 인증이 부족하다.

공격 기법 종류

CSRF는 대부분 URL을 사용자가 접근하게 될 경우 비정상적이고 악의적인 요청이 서버로 전송되도록 합니다. 다만, XSS와 연계하여 사용할 경우 그 방식이 더욱 다양해질 수 있습니다. XSS와 함께 사용되는 공격 특징 때문에 XSS와 더더욱 헷갈리기 쉽습니다.

  1. CSRF only (Link + GET method)
  2. CSRF(link) + Spoofing
  3. XSS + CSRF

위험성

CSRF는 XSS와 마찬가지로 범위가 넓어서 취약점이 빈번하게 발견될 수 있습니다. 다만, 모든 요청이 절대 취약점으로써 인지 될 필요가 없을 수도 있습니다. 발견된 CSRF 취약점이 컨설턴트의 주관과 공격자의 입장에 선 시나리오 등의 상상력에 따라서 보완 여부가 결정될 수 있습니다. 보안컨설턴트의 입장에서도 다양한 시나리오를 고려해서 적절한 설명을 곁들여서 클라이언트에게 설명해 줄 필요가 있습니다. 예를 들어 비밀번호를 변경시키는 CSRF 취약점이 존재한다면 공격자가 사용자의 비밀번호를 변경하여 권한을 상승시키거나 인증을 우회하는 등의 문제가 생길 수 있으며 희생자가 관리자 계정이나 그에 준하는 권한을 가진 사람이라면 피해가 더 커질 수 있음을 설명하는 것이 될 수 있겠습니다. 그보다 애매한 예시라면 게시판이 될 수 있습니다. 하지만 게시판의 경우도 관리자 계정을 공격하여 성공한다면 치명적인 영향이 생길 수 있습니다.

 

공격 단계

CSRF의 공격 단계는 우선 취약점의 존재 여부를 식별하고 요청이 전송이 되는지, 변조가 되는지 등을 파악해서 파라미터를 생성합니다. 추가적으로 XSS 취약점을 파악해서 함께 활용할 수 있는지 여부를 검토합니다. 

  1. 중요한 요청 식별 (ex: 비밀번호 바꾸기, 2차 인증 해제, 계좌번호 열람 등)
  2. 위의 요청을 재생산할 수 있는지 체크 (Burp Suite의 repeater 활용 가능 여부, 인증정보 유무)

위 2단계가 성공했다면 CSRF의 취약점이 존재한다고 유추할 수 있습니다.

이제 GET 방식으로 Request를 보낼 수 있는지 확인하고 작동한다면 공격자는 링크를 제작해서 피해자에게 유도할 수 있습니다. 이것에 대한 1차적인 대응으로 POST 방식으로 Request를 받도록 할 수 있습니다.

  • 공격 시나리오 1 : GET Request
  • 대응 : POST 방식으로 파라미터 받기

하지만, POST방식으로 파라미터를 받는 것은 도메인 내에 XSS 취약점이 존재한다면 충분히 우회할 수 있습니다.

  1. XSS 취약점 식별
  2. Form 태그를 통해 POST 요청 전송

Form 태그를 통해 요청을 전송하는 페이로드를 작성하고 XSS를 통해 해당 요청을 전송하도록 심어놓는다면 POST 방식으로도 요청을 피해자의 권한으로 전송할 수 있게 됩니다. 이것에 대한 1차적인 대응은 CSRF 토큰을 추가해서 요청을 전송할 때에 해당 토큰을 받아야만 요청이 수행될 수 있도록 하는 방법이 있습니다.

  • 공격 시나리오 2 : POST Form + XSS
  • 대응 : CSRF 토큰

물론, CSRF 토큰을 사용하더라도 XSS 취약점이 이미 있다고 가정한다면 자바스크립트를 잘 활용해서 페이로드를 정교하게 디자인하여 토큰을 탈취한 뒤에 요청을 재전송할 수 있습니다. 이것에 대한 대응은 Referer 헤더 값을 체크하여 특정 위치에서만 요청이 전송되도록 확인하는 것이 있습니다.

  • 공격 시나리오 3 : POST Form + XSS + CSRF Token Hijacking
  • 대응 : Referer 헤더 체크

이제 Referer 헤드까지 체크를 정확하게 수행한다면 우회할 수 있는 방법은 없다고 볼 수 있습니다. 하지만, 개발자의 입장에서 잘못된 예외 허용을 하거나 체크에 대한 구현이 미흡하게 되었을 경우 CSRF 공격이 실행(허용)될 수 있습니다.

실제 개발의 영역에서는 CSRF토큰과 Referer를 구현했지만 예외 허용을 통해서 CSRF 토큰이 없거나 Referer 헤더가 없는 경우에도 요청이 전송되도록 하는 경우가 생길 수 있습니다. 이러한 경우에는 단순히 파라미터를 지우는 것으로 우회할 수도 있습니다. 

  • 공격 시나리오 4 : 파라미터 미입력
  • 대응 : 잘못된 예외 허용 금지

대응법

근본적인 대응법은 아래와 같습니다.

  1. 민감한 요청 전송시 기존 비밀번호(추가 인증요소) 입력
  2. 2차 인증 토큰 사용(CSRF Token)
  3. Referer 헤더 체크

위의 대응법을 동시에 적절히 사용해 준다면 CSRF의 주 목적인 비밀번호 변경과 같은 요청을 방어할 수 있고, 그 외의 다수의 요청도 방어할 수 있습니다. CSRF가 url 형태로 공격이 자주 이루어 지므로 GET 방식 대신 POST 방식으로 값을 전송하는 것도 대응법이라고 생각하기 쉽지만 XSS와 연계하여 공격한다면 비교적 쉽게 우회할 수 있습니다. XSS가 빈번하게 일어나는 취약점이라는 것을 고려하면 그렇게 좋은 대응방식은 아닙니다. 또한, 토큰의 경우도 충분히 우회가 가능하다는 것과 구현의 불편함 때문에 개발자에게 꺼려지는 요소이기도 합니다. Referer 헤더를 체크하는 경우 '잘못된 예외 허용'

없이 잘 구현된다면 CSRF 공격으로부터 매우 안전하다고 할 수 있습니다. 가장 근본적으로 좋은 대응법은 중요한 요청을 전송할 때 인증정보(기존 비밀번호, 2차 비밀번호, 핸드폰 번호, 주민등록번호 등)를 입력하도록 하는 것입니다. 대부분의 사이트에서는 이러한 인증요소를 통해 CSRF 공격으로부터 보호하고 있습니다.