해커가 유저의 권한을 도용하여 특정 웹사이트에 요청을 하는 공격이다. 유저가 특정 웹사이트에 로그인한 상태로 CSRF 공격 코드가 들어있는 페이지를 열면 유저의 의지와 무관하게 유저의 웹 브라우저와 공격 대상인 웹 사이트 간에 상호작용이 이루어지게 된다. (ex 이메일에 첨부된 링크를 클릭했더니 페이스북 내 계정에 내가 쓰지 않은 광고성 글이 등록되었다.)
XSS(Cross-Site Scripting)이 유저가 특정 웹사이트를 신용하는 점을 노린 것이라면 CSRF는 특정 웹사이트가 유저의 웹 브라우저를 신용하는 상태를 노린 공격이다.
유저의 컴퓨터를 감염시키거나 서버를 해킹한 공격은 아님.
CSRF 공격이 이루어지기 위한 조건
타겟 웹사이트에 유저가 로그인한 상태
유저가 CSRF 공격 코드가 들어있는 웹 페이지에 접속
CSRF 공격 방어
보통 데이터 조회(GET)보다 쓰기/변경(POST/DELETE)에 초점을 둔다
CSRF Token
서버에 들어온 요청이 실제 유저의 웹 브라우저에서 온 것인지 확인하기 위해 토큰을 유저의 브라우저에만 제공
Same-Site Cookie
같은 도메인 내에서만 세션/쿠키 사용 가능
토큰 기반 인증
서버에서는 토큰을 발행만 하고 저장은 클라이언트에서 한다. 그래서 세션 방식과 비교할 때 토큰 방식은 서버의 부담을 덜어주고 서버 분산 환경에 더 유연하게 사용할 수 있다. 앱을 확장할 예정이라면 토큰 기반 인증을 사용하는 것을 고려해볼 만 한다.
토큰 기반 인증은 stateless하다. 인증정보가 서버나 세션에 담아두지 않는다.
한번 발급된 토큰은 계속해서 사용할 수 있기 때문에 Access Token의 유효기간을 짧게하고 Refresh Token(Access Token을 새로 발급해주는 토큰)을 발행하여 피해를 줄일 수 있다. (완벽하지 않음 한계 존재)
토큰을 localStorage에 저장하면 XSS 공격에 취약해진다. 쿠키에 저장하면 스크립트 실행을 막아줄 수는 있지만 CSRF에는 여전히 취약하다.