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 %}