Cross Site Request Forgery : 사이트간 요청위조, 웹사이트 취약점 공격 중 하나에 속함
**
**
XSS와 CSRF의 차이
전제조건을 만족해야 한다.
(1) 사용자(희생자, 자기도 모르게 공격되는 사람)은 보안이 취약한 서버에 이미 로그인 되어있어야 한다.
(2) 쿠키 기반의 서버 세션정보를 획득할 수 있어야한다.
(3) 공격자는 서버를 공격하기 위한 요청방법을 미리 파악하고 있어야 한다.
▪️ 예상치못한 파라미터가 있으면 불가능하다.
(1) 먼저 공격자는 “조건 3번”을 통해서 서버를 공격하기 위한 요청방법을 미리 파악하고 있는 상태다.
(2) 아무것도 모르는 사용자(희생자)는 보안이 취약한 서버에 로그인한다.
로그인 이후, 세션정보를 활용할 수 있는 sessionID가 사용자 브라우저 쿠키에 저장된다.
(3) 공격자는, 서버에 인증된 브라우저 사용자가 악성 스크립트 페이지를 누르도록 유도한다.
(4) 사용자가 악성 스크립트가 담긴 페이지 접근시, 쿠키에 저장된 SessionID는 브라우저에 의해 자동적으로 함께 서버에 요청된다.
(5) 서버는 쿠키에 담긴 SessionId를 통해 이미 인증받은 사용자에게 온 것으로 인식하고 요청에 대한 처리를 하게 된다.
즉, 공격자가 의도한 행동을 하게 된다.
가끔 프로젝트 코드를 보면 csrf를 disable()한 것을 볼 수 있다.
implementation 'org.springframework.boot:spring-boot-starter-security'
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter { }
따라서 악성 스크립트 페이지를 요청하려고 할 때 403 forbidden
으로 반환해서 막아준다.
근데 왜 disable할까?
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
서버에서 사용자의 요청헤더에서 Referrer
정보를 확인하는 방법이다. 보통 호스트와 Referrer 값이 일치하므로 둘을 비교한다. 대부분 Referrer 값에 대한 검증만으로 방어가 가능하다고 한다.
String referer = request.getHeader("Referer");
String host = request.getHeader("host");
if (referer == null || !referer.contains(host)) {
response.sendRedirect("/");
return false;
}
return true;
임의의 CSRF 토큰을 만들고 세션에 저장한다. 이후 요청하는 페이지에 hidden타입의 input 태그로 토큰값을 함께 전달한다. 이후 서버에서 세션에 저장된 CSRF 토큰값과 요청 파라미터에 담긴 토큰값을 비교한다.
사용자가 특정 서버에 로그인하려면 일반적으로 아래의 작업이 수행된다.
(1) 서버는 로그인시 인증된 사용자의 정보를 세션에 저장하고, 이를 찾을 수 있는 sessionId
를 만든다.
(2) 서버는 저장된 세션정보를 클라이언트(브라우저)가 사용할 수 있도록 sessionID를 set-Cookie 헤더에 담아서 전달한다.
(3) 클라이언트는 전달된 sessionID를 쿠키에 저장한다.
(4) 클라이언트는 같은 서버에 요청할 때 쿠키에 저장된 sessionID를 자동으로 쿠키에 담아 전달한다.
(5) 서버는 쿠키에 담긴 sessionID를 통해 인증된 사용자인지 여부를 확인해서 응답을 보낸다.
Spring security - csrf란?
CSRF(Cross-Site Request Forgery) Attack and Defence