CSRF (Cross Site Request Forgery)

고둑·2021년 11월 27일
0
post-thumbnail

이번에 정리할 주제는 CSRF 공격이다. (이번 주 자격증 준비부터 시작해서 너무 바빴어요....)

해군 정보보호병 지원을 위해 쭉 달려왔던 일주일이었다. 자격증 공부에 면접 예상 질문까지 찾아보았는데 기술 면접 중에 XSS(Cross Site Scripting)과 CSRF(Cross Site Request Forgery)의 차이를 물어보는 질문이 있었고 몇 달전 현준이형 스터디를 듣다가 면접에서 초짜들을 떨구는 질문 중에 한 가지로 자주 이용한다고 했던 기억이 나서 겸사겸사 CSRF를 정리하게 되었다.

CSRF 공격은 웹 어플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 만드는 공격이라고 합니다.
한 마디로 실제 권한을 가진 사용자의 의지와 상관없이 권한을 공격자 마음대로 활용할 수 있도록 만들어 주는 취약점입니다.

CSRF는 아래와 같은 과정을 이용하여 공격을 합니다.

CSRF를 성공적으로 사용하기 위해서는 다음과 같은 조건이 만족되어야한다.

  • 위조 요청을 전송하는 서비스에 희생자가 로그인 상태
  • 희생자가 해커가 만든 피싱 사이트나 게시글에 접속

이러한 조건을 달성하기 위해 공격자들은 XSS와 CSRF를 같이 쓰기 시작했다.
나중에 XSS에서 자세히 말할거지만 Stored XSS를 활용하여 피싱 게시글이나 페이지를 만든 뒤 클릭하는 희생자들의 정보를 탈취하고 얻은 정보를 이용하여 CSRF를 사용하는 패턴이 많이 이용된다.
따라서 많은(?) 사람이 XSS와 CSRF를 혼동하는거같다.

XSS와 CSRF의 가장 큰 차이는 서로 공격을 수행하는 지점이 다르다는거다.
XSS는 클라이언트가 페이지를 믿는다는 전제를 깔고 클라이언트 사이드로 공격을 진행하고 CSRF는 서버가 응답받은 데이터를 믿는다는 것을 전제로 까고 서버를 공격하는 방식이다.
따라서 XSS는 클라이언트 사이드를 공격을 진행하는 것이고 CSRF는 서버 사이드를 공격하는 것이라고 생각하면 된다.

실제로 CSRF 공격 방식을 알아보도록 하겠다.
<img src="http://borntobehacked.com/chageaccount?id=hacker&pw=1234" width="0" height="0">

이런 상태의 코드를 공격자가 심어놓았다고 생각해보자
이런 코드가 있는 사이트를 방문하게 되면 <img>태그를 로딩하게 되는 과정에서 src에 있는 주소로 요청을 보내게 된다. 이때 요청을 보내는 주소 값은 chageaccont라는 계정 아이디와 비밀번호를 바꾸는 기능을 담당하게 되는 페이지이고 매개변수로 바꿀 아이디와 비밀번호를 넘기게 된다.
따라서 피해자는 단순히 저 코드가 삽입된 페이지에 방문하는 것만으로도 사용자의 아이디와 비밀번호에 해커가 사전에 설정해 놓은 정보로 계정 정보가 바뀌게 되고 그대로 계정이 해킹당하게 된다. 이게 가장 무서운게 특정 사용자 한 명을 타겟으로 하는게 아닌 여러명의 불특정 다수를 상대로 공격이 할 수 있다는 것이 정말 무서운 것이다.
그래서 전문가들이 링크가 오면 확실한 출처가 아니면 들어가지 말라하는 것이다. (이렇게 말해도 부모님은 그냥 모든 링크 다 들어가긴 하던데...)

하지만 다행히 요즘 실제 서비스 중인 사이트에서 이렇게 GET방식으로 중요한 정보를 다루는 지성과 숨바꼭질하는 행위는 하지 않는 사이트가 대부분이다. 따라서 POST, DELETE, PUT, PATCH 방식만 조심히 필터링하면 편하다.

CSRF를 방어하는 방법에는 크게 2가지 존재한다.
첫번째 방법은 저번에 정리를 했던 SOP(Same-origin Policy)를 검증하는 방법이다.
SOP는 저번에 CORS에서 정리했다.

대부분의 Request 헤더는 Origin Header나 Referer Header 둘 중 하나 이상을 가지고 있으며 이를 통해 Same-origin Policy를 검증할 수 있다.
Origin Header가 존재할 경우, 이를 통해서 웹사이트의 origin을 검증할 수 있고 Origin Header가 없을 경우, Referer Header 내의 호스트명과 웹사이트의 Origin을 비교하여 검증할 수 있다.
만약 2가지 다 없으면 응답을 받거나 거절하는 건 개발자 선택이다.
하지만 위 방법은 XSS와 같이 CSRF를 트리거하면 쉽게 우회할 수 있다.

두번째 방식은 Security Token(CSRF Token)을 사용하는 것이다.
사용자의 세션에 임의의 난수 값을 저장하고 사용자의 요청 마다 해당 난수 값을 포함 시켜 전송시킵니다. 이후 Back-end 단에서 요청을 받을 때마다 세션에 저장된 토큰 값과 요청 파라미터에 전달되는 토큰 값이 일치하는 지 검증하는 방법이다.
이 방식도 XSS를 트리거하는것으로 쉽게 우회할 수 있게 된다.

따라서 일단 CSRF를 안정적으로 막으려면 XSS를 막아야 하는 것을 알 수 있다.

다음에는 XSS에 대해 정리해보도록 하겠다.

profile
문워킹은 하지말자

0개의 댓글