웹개발을 해본 사람이라면 CSRF에 대해 들어봤을 것이다. 나 또한 GET 방식을 제외한 요청에서 CSRF Token
을 쓰면서 보안 관련된 거라는 건 대충 알았는데, 정확히 뭔지 와닿지 않았었다. 결론부터 얘기하면, CSRF
는 사이트간 요청 위조
를 의미한다. 웹사이트의 취약점을 이용하여 사용자가 의도하지 않은 요청을 보내게끔 하는 공격이다.
HTTP는 stateless의 특성을 가지므로 요청 간의 상관관계를 특정할 수 없다. 따라서 사용자(피해자)가 로그인 등을 통해 인증되거나 특정 권한을 갖고 있다면, 공격자가 그를 이용해 등록/수정/삭제 등을 할 수 있게 되는 것이다.
CSRF 공격이 이루어지기 위한 조건
- 웹서비스(네이버 등…)에 사용자가 로그인한 상태
- 사용자가 해커가 만든 피싱 사이트에 접속
요즘은 자동로그인을 설정해두는 경우가 많으니, 피싱 사이트에 접속했다가는 이 공격에 당할 가능성이 충분히 생긴다.
CSRF 방어 방법
Referrer 검증
- Request의
Referrer
를 서버단에서 확인하여 도메인이 일치하는지 검증하는 방법이다. - 일반적으로 Referrer 검증만으로 대부분의 CSRF 공격을 방어할 수 있다.(단, 같은 도메인 내의 페이지에 XSS 취약점이 있는 경우 CSRF 공격에 취약해질 수 있다.)
Security Token 사용
Referrer 검증이 불가한 환경이라면, Security Token
를 활용할 수 있다.
-
CSRF Token 검증
- 우선 사용자의 세션에 임의의 난수값을 심어두고 사용자가 Request 할 때마다 해당 난수 값을 포함 시키게 해 일치여부를 확인하는 것이다.
- 이 방법도 결국 같은 도메인 내에 XSS 취약점이 있다면 CSRF 공격에 취약해진다.
-
Double Submit Cookie 검증
- 스크립트 단에서, Request 시 난수 값을 생성하여 쿠키에 저장하고 동일한 난수 값을 Request의 Parameter 혹은 Header에도 저장하여 서버로 전송한다. 이렇게 두 군데에서 온 토큰값이 일치하는지를 확인하는 것이다.(따라서 서버에 토큰값을 저장해둘 필요가 없다.)
- 세션을 사용할 수 없는 환경에서 사용할 수 있는 방법으로, 웹브라우저의
Same Origin Policy
로 인해 자바스크립트에서 타 도메인의 쿠키값을 확인/수정하지 못한다는 것을 이용한 기법이다. - 쉽게 말해, 공격자가 쿠키값을 건들지는 못하므로 유효해지는 방법이다.