CSRF(Cross-Site Reqeust Forgery)
- 사이트 간 요청 위조
- 사용자의 의지와 무관하게, 사용자의 요청에 공격자가 의도한 행위를 담아 특정 웹사이트에 요청하도록 위조하는 것
CSRF 공격
CSRF 공격이 가능한 조건
- 사용자가 이미 인증된 상태일 것
인증된 사용자가 가진 권한의 범위에서 악의적인 행위를 할 수 있다. - 쿠키를 기반으로 한 세션 인증을 사용하는 환경일 것
사용자가 사이트에 요청을 보내면 브라우저가 갖고 있는 쿠키는 서버에 자동으로 전달되기 때문이다. - 공격자는 서버를 공격을 위한 요청방법을 미리 파악하고 있을 것(예측 불가한 파라미터가 없을 것)
CSRF 공격 과정
- 사용자가 로그인(인증)
- sessionID가 사용자 브라우저의 쿠키에 저장 됨
- 사용자가 악성 스크립트 페이지를 누르도록 유도 (메일 등으로 악성 스크립트가 담긴 링크/이미지 등을 전달)
- 사용자가 서버에 요청을 보낼 경우 쿠키에 저장된 sessionID는 브라우저에 의해 서버에 전달됨
- 서버는 쿠키에 담긴 sessionID를 통해 요청자가 인증된 사용자임을 판단하고 요청을 처리
CSRF 피해 사례
2008년 옥션에서 대규모 사용자 정보 탈취 사건이 발생했던 것도 관리자 계정을 통해 CSRF 공격을 했기 때문이라고 한다. CSRF 사례 검색하면 항상 나온다. 영원히 고통받는 옥션
- 관리자는 로그인 상태
- 공격자가 관리자에게 아래의 코드가 담긴 이메일을 보냈고
<img src="http://auction.com/changeUserAccount?id=admin&password=admin" width="0" height="0"/>
- 관리자가 해당 메일을 열었을 때, 이미지를 받아오기 위해 해당 URL이 열린다.
이미지 크기가 0이기 때문에 관리자는 이미지가 있는지조차 알지 못한다. - 관리자 계정의 id와 pw가 모두 admin으로 변경된다.
CSRF 공격 방법
- POST 방식 CSRF 공격
사용자가 아래와 같은 html이 포함된 페이지를 열람할 경우, 사용자는 자신도 모르게 post 요청을 보내게 된다.
(페이스북에 "지금 가입 시 즉시 아이템 지급" 이라는 게시글을 작성)
<form action="http://facebook.com/api/content" method="post"> <input type="hidden" name="body" value="지금 가입 시 즉시 아이템 지급" /> <input type="submit" value="Click Me"/> </form>
- GET 방식 CSRF 공격
사용자가 아래와 같은 html이 포함된 페이지를 열람하는 경우, 사용자는 자신도 모르게 get 요청을 보내게 된다.
<div> <img src="요청을 보낼 주소" width="0" height="0" /> </div>
CSRF 방어 방법
- Referer 검증, CSRF 토큰 검증, double submit cookie 검증, captcha 등이 있다.
- Spring Security에서는 @EnableWebSecurity 어노테이션 사용 시 CSRF 방어 기능이 활성화 된다.
- HTTP 형식을 따르는 stateless한 Rest Api 방식은 쿠키를 사용하지 않으므로 CSRF 공격이 불가하여 방어할 필요가 없다.
Referer 검증
- 서버단에서 요청의 referer를 확인하여 domain의 일치 여부를 검증하는 방법
- Request Header는 요청이 발생한 페이지의 주소를 담고 있다. 이를 활용해 요청을 받는 서버는 정해진 referer만 허용하는 로직을 추가할 수 있다. 즉, 동일한 도메인 상에서 들어온 요청이 아니라면 예외를 발생시킨다.
- Request header에 있는 host, referer 가져오기
보통 호스트와 referer 값이 일치하므로 이 둘을 비교한다.
String host = request.getHeader("host"); String referer = request.getHeader("Referer"); //이후 referer가 존재 하는지, host와 referer가 일치하는지 검증
- referer 검증만으로 대부분의 csrf 공격을 방어할 수 있다고 한다.
- 주의점 : 같은 도메인 내의 페이지에 XSS 취약점이 있을 경우 CSRF 공격에도 취약해질 수 있다.
CSRF 토큰 검증
- session과 연결된 랜덤값을 가진 토큰을 발행하고, 요청이 들어올 때 토큰 값을 검증하는 방법
- 로그인 시 CSRF 토큰을 생성해서 세션에 저장하고, CSRF 토큰을 요청 태그에 hidden 값으로 넣어두어 요청마다 CSRF 토큰을 포함시킨다. 서버에서는 요청이 들어오면 세션과 파라미터에 담긴 CSRF 토큰 값의 일치 여부를 검사하고, CSRF 토큰이 존재하지 않거나 기존의 토큰과 일치하지 않을 경우 4XX 상태코드를 반환한다.
- CSRF 토큰 포함 예시
//CSRF 토큰 생성하여 세션에 저장 session.setAttribute("CSRF_TOKEN", UUID.randomUUID().toString()); //CSRF 토큰 셋팅하여 서버에 전송 <input type="hidden" name="_csrf" value="${CSRF_TOKEN}" /> ... //세션에 저장된 csrf 토큰과 파라미터로 전달된 csrf 토큰 값 가져오기 String csrfParam = request.getParameter("_csrf"); String csrfSession = request.getSession().getAttribute("CSRF_TOKEN"); //이후 두 값이 일치하는지 검증
Double Submit Cookie 검증
- 브라우저의 same-origin 정책을 이용하여, same-origin이 아닌 경우 js에서 타 도메인의 쿠키 값 조회/수정이 불가한 점을 이용한 검증방법
- 세션을 사용할 수 없는 환경에서 사용할 수 있다.
- 클라이언트에서 js로 임의로 생성한 토큰을 쿠키와 요청 헤더에 각각 담아서 서버에 전달하면, 서버는 전달받은 쿠키와 요청 헤더에서 토큰을 꺼내 이를 비교한다. 이때 쿠키에 저장된 토큰 정보는 만료처리되어 이후 재사용이 불가능하다.
CAPTCHA
- "로봇이 아닙니다"를 체크하거나 그림에 있는 문자를 입력하는 등의 방식으로 해당 요청이 봇에 의한 요청인지 아닌지를 검증하는 방법
- 자동화 도구들에 의한 요청 방지 밋 공격자가 요청 인자를 파악하지 못하게 하여 CSRF 공격을 방어할 수 있다.
CSRF 방어 취약점
- 방어 기법을 잘못 설정할 경우, CSRF 공격이 가능해질 수 있다.
- CSRF 방어 시 고려할 점은 https://cosyp.tistory.com/244 의 3. CSRF 취약점 참고하면 좋을 듯 하다.
근데 Spring Security 예시 코드에서는 왜 대부분 csrf().disable();을 설정할까?
- Spring Security에 대해 찾아보면 세션과 쿠키를 사용하는 환경이면서도 개발 편의성을 위해 csrf disable 설정을 하라는 글이 많다. 근데 CSRF에 대해 찾아보니... 이거 disable해도 되는 거 맞나 싶다.
- 검색해보니 Spring Security에서는 CSRF 공격을 방어하기 위해 CSRF 토큰 검증 방식을 사용하는데, csrf 방어를 활성화 할 경우 CSRF 토큰값을 넣어주는 작업이 필요하다고 한다.
https://baessi.tistory.com/99?category=1046287 / https://taesan94.tistory.com/134
아마 이 부분을 생략하기 위해서 그런 것으로 보인다.
참고
CSRF(Cross-Site Request Forgery) 공격과 방어 - Junhyunny’s Devlogs
CSRF(Cross-Site Request Forgery) 공격과 방어
junhyunny.github.io
https://docs.spring.io/spring-security/site/docs/5.3.x/reference/html5/#csrf
Spring Security Reference
In Spring Security 3.0, the codebase was sub-divided into separate jars which more clearly separate different functionality areas and third-party dependencies. If you use Maven to build your project, these are the modules you should add to your pom.xml. Ev
docs.spring.io
CSRF 공격이란? 그리고 CSRF 방어 방법
CSRF 공격(Cross Site Request Forgery)은 웹 어플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게
itstory.tk
Spring Security - CSRF(Cross-Site Request Forgery) (tistory.com)
Spring Security - CSRF(Cross-Site Request Forgery)
• 안녕하세요~ 이전에 운영하던 블로그 및 GitHub, 공부 내용을 정리하는 Study-GitHub 가 있습니다! • 네이버 블로그 • GitHub • Study-GitHub • 🐔 📎 CSRF(Cross-Site Request Forgery) 안녕하세요,..
zzang9ha.tistory.com
[WEBHACKING] CSRF에 대해서
1. CSRF란? CSRF는 Cross-Site Request Forgery의 약자로 다른 사이트에서의 변조된 요청을 의미한다. 해당 공격은 공격자가 피해자의 권한으로 특정 행위를 하도록 인자값들을 구성해서 피해자가 본인도
cosyp.tistory.com
'기타' 카테고리의 다른 글
iconsax 아이콘 figma에 추가하기 (0) | 2023.08.12 |
---|---|
JMeter에서 JWT 넣어주기 (0) | 2022.08.24 |