1. 목적

옥션의 개인정보 요출의 주범 CSRF 대응 방안을 고민해보자.


2. 가급적 HTTP 메소드 오버라이드를 하지 않는다.

폼에서 PUT, DELETE 등을 사용하기 위해 method-override, HiddenHttpdMethodFilter 등을 사용하는 경우가 많다. 이 경우 취약점이 될 수 있으니 주의하자.


3. CORS 

특별한 요구사항이 없다면 disable 한다. 이 밖에 Apache HTTP Server 웹 서버의 CORS 설정을 참고하라.


4. 토큰 사용

Client - Server 간 토큰 방식의 인증을 수행한다.

4.1. Spring Security

스프링을 사용하고 있다면 Spring Security를 활용해본다. 하지만 토큰 방식도 iframe 등으로 우회할 수 있으므로 capcha 적용 등도 고민해볼 수 있다.

4.2. SavedToken

4.2.1. 기능

DevOn Frame은 SavedToken이라는 기능을 제공한다.

  • 처음에 클라이언트와 서버에 동일한 토큰(Unique한 값)을 생성하고 서버 세션이 저장
  • 서버에 요청되면 파라미터의 토큰값과 세션의 토큰값을 비교하여 유효한 요청인지 확인하고 유효하지 않으면 SavedTokenException
  • Skip URL 기능이 있어 URL 패턴에 따라 토큰 체크 생략 가능

4.2.2. 설정

사용 시에는 SavedTokenInterceptor를 Bean으로 등록하고 HandlerMapping의 interceptors에 추가한다. 속성에는 다음과 같다.

  • scope : 토큰의 범위를 설정한다.
    1) REQUEST : 세션에 저장되는 토큰 값이 request시마다 변경
    2) SESSION : 세션에 저장되는 토큰 값이 session이 새로 생성될 때만 변경
  • skipUrls : 토큰 체크를 제외할 URL 패턴 (리스트로 여러 형태 지정 가능)

4.2.3. 화면처리

<form> 태그 내부에 <Tag:savedToken/> 태그 추가하여 (+이를 위해 태그 라이브러리 선언도 필요), request 파라미터에 토큰값이 담기도록 한다.


5. Django 플랫폼 사용시

장고(Django)는 1.2 버전부터 기본적으로 CSRF 취약점을 막는 기능을 제공한다. 모든 POST 방식의 폼 전송 시 hidden 필드로 세션에 따른 임의 키값을 전송하고, 그 키 값이 유효한지를 확인한다. 이 기능을 사용하기 위해서는 다음과 같이 처리한다.
 
   1. settings.py에 미들웨어에 django.middleware.csrf.CsrfViewMiddleware를 추가한다.
   2. POST가 포함된 폼에 {% csrf_token %} 을 직접 삽입해야 합니다.
<form action="" method="post">{% csrf_token %}