Ruby On Rails에서는 CSRF를 방지하기 위해 기본적으로 "form_authenticity_token"이라는 걸 제공한다.
(기본적인 보안을 왠만큼 해준다는건 너무 편하다 ㅠ_ㅠ.. 프레임워크를 쓰는 장점이랄까..) 폼을 통해 어떤 정보를 서버로 보낼때 인증키값을 추가로 보내고 서버에서 키값을 확인하여 정상적인 요청인지를 확인하게 되는 것이다. CSRF라는 놈을 막는법부터 설명 했는데, 그렇다면 CSRF란 놈이 뭐하는 녀석인지 알아보자.
1. 사례 그냥 갑자기 생각난건데 -_-, 사내 홈페이지의 보안이 허술하다면 이런것도 가능하겠다... 휴가 신청서를 작성한 후, 팀장에게 아무 내용이나 적어서 메일을 보낸다. 팀장이 메일을 읽으면 해당 신청서가 자동으로 승인이 떨어지고 목록에서 자동으로 삭제 된다. 팀장도 모르는 사이 승인을 해준꼴이 된다.
물론...!! 이보다 더 심한 일도 충분히 발생 가능하다!!
2. 어떻게? 팀장이 승인 버튼을 누를때 호출하는 링크가 http://..../confirm.jsp?id=5123 라고 해보자. 그냥 단순히 메일을 보낼때 해당 링크를 img 테그로 보내면 되는거다. 요즘 보안때문에 iframe, javascript등은 막지만 image는 보통 막지 않는다. 따라서 <img src="http://.../confirm.jsp?id=5123" width="0" height="0"> 같은걸 메일로 보내고 그걸 읽는 다면 자동으로 저 링크를 클릭한 것과 같은 효과를 볼 수 있다. 운이 좋게 팀장이 회사 홈페이지를 로그아웃 한 상태라면 큰 문제가 없겠지만, 로그인 상태에서 메일을 읽는다면 세션이 남아 있으므로 아무 문제 없이 승인처리가 될 것이다.
3. 막는법 첫번째로, 페이지를 이동할 경우 꼬박꼬박 사용자가 로그아웃 한다. 두번째로, 서버에 어떤 작업을 요청을 할 때 세션이외에 다른 확인절차를 추가한다. 첫번째는 사용자마다 항상 지킬 수 없기 때문에 완벽하지 않고, 두번째는 인증키값을 form에 삽입하여 간단하게 처리할 수 있다.
<input name="authenticity_token" type="hidden" value="b016c7698ea9df4f6ef0621dd84ac32dde54cb7e" />등을 form에 삽입하고 해당값을 쿠키 또는 서버에 저장해 놓았다가 작업 요청시 쿠키 또는 서버에 저장해둔 값과 인증키값을 비교하여 처리하면 되겠다.
4. 결론 로그인 체크, 세션확인, 다운로드 절대 경로 체크등의 보안은 대부분 잘 지키고 있으나 CSRF보안을 지키지 않는 곳은 꽤 되는듯 하다. 옥션에서 1800만 명 개인 정보 유출 사고도 CSRF 공격을 받은 걸로 밝혀졌다.
간단한 인증 키값 체크 만으로도 방지할 수 있으니 개발자는 항상 보안에 신경 쓰고 조치를 해야 하겠다.