표준프레임워크 3.x(Spring Security 설정 간소화) 환경에서 CSRF 방어를 적용하는 방법을 안내 드립니다.
■ 배경
표준프레임워크 3.x의 Spring Security 설정 간소화(<egov-security:config>)에는 CSRF 설정 항목이 제공되지 않으며, 설정 파일에 <csrf />를 직접 추가하면 다음 오류가 발생합니다.
java.lang.IllegalArgumentException:
A universal match pattern ('/**') is defined before other patterns in the filter chain |
이는 실행환경 보안 라이브러리(egovframework.rte.fdl.security)의 초기화 클래스가 jar 내부의 기본 설정 파일(/META-INF/spring/security/security-config.xml)을 로딩하는 과정에서 사용자 추가 설정과 로딩 순서 충돌이 발생하기 때문입니다.
■ 조치 원리
WAS 클래스로더가 /WEB-INF/classes 를 /WEB-INF/lib(jar)보다 먼저 로딩하는 점을 이용하여, 초기화 클래스를 프로젝트에 동일 패키지·동일 이름으로 재정의하고 <csrf />가 추가된 security-config.xml 을 로딩하도록 합니다. (Java Servlet 스펙)
■ 1단계 : 초기화 클래스 재정의
src/main/java 에 egovframework.rte.fdl.security.config 패키지를 생성하고, jar 내부 원본과 동일한 내용으로 EgovSecurityConfigInitializerBeanDefinitionParser 클래스를 작성하되 security-config.xml 로딩 경로만 아래와 같이 변경합니다.
|
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
LOGGER.debug("Load '/egovframework/spring/com/security-config.xml'");
parserContext.getReaderContext().getReader()
.loadBeanDefinitions("classpath*:/egovframework/spring/com/security-config.xml");
...
}
|
■ 2단계 : security-config.xml 복사 후 <csrf /> 추가
jar 내부의 security-config.xml 을 리소스 /egovframework/spring/com/ 폴더에 복사한 뒤, <http> 요소 안에 <csrf />를 추가합니다.
(스프링 시동 시에는 context-*.xml 패턴의 파일만 로딩하므로 중복 로딩은 발생하지 않습니다.)
|
<http entry-point-ref="loginUrlAuthenticationEntryPoint" request-matcher-ref="requestMatcherTypeFactoryBean">
<form-login />
<logout />
<anonymous />
<csrf />
...
</http>
|
■ 3단계 : WAS 재시작 및 적용 확인
WAS 재시작 시 CSRF가 활성화됩니다. 스프링 폼 태그(<form:form>)를 사용하는 폼에는 CSRF 토큰이 자동으로 삽입됩니다.
<!-- 예시 -->
<input type="hidden" name="_csrf" value="9deb4a24-2331-4f14-9333-6b8f8f146b37" /> |
■ 4단계 : 일반 HTML 폼에 토큰 수동 삽입
스프링 폼 태그를 사용하지 않는 일반 <form>(POST 방식)에는 아래 한 줄을 추가해야 하며, 누락 시 해당 요청은 403 오류로 차단됩니다. (로그인 폼 포함)
| <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> |
■ 5단계 : 로그아웃 방식 변경
CSRF 활성화 시 로그아웃 URL(/j_spring_security_logout)은 GET이 아닌
POST 방식으로 호출해야 합니다.
■ 적용 확인 방법
- 화면 소스에서 폼 내부에 _csrf 히든 필드가 생성되는지 확인
- 토큰을 제거하거나 임의 값으로 변조한 POST 요청이 403(Forbidden)으로 차단되는지 확인
- 정상 토큰을 포함한 요청은 기존과 동일하게 처리되는지 확인
■ 참고
- 대상 : 표준프레임워크 실행환경 3.0 , 3.1 , 3.5 , 3.6 (Spring Security 3.2.4 기반 설정 간소화 사용 시)
- 세션이 새로 생성되면 토큰도 재발급되므로 페이지마다 서버가 렌더링한 최신 토큰을 사용해야 합니다.