메뉴 건너띄기
주메뉴 바로가기
본문 바로가기

이 누리집은 대한민국 공식 전자정부 누리집입니다.

본문 영역

적용 지원, FAQ, Q&A 게시판을 통해 기술 문제 해결을 지원합니다.

자주 묻는 질문

표준프레임워크 실행환경 v3.0 ~ v3.6 시큐리티 간소화 서비스 사용시 CSRF 취약점 대응방법
  • 작성자

    관리자

  • 작성일자

    2026-08-14

  • 조회수

    24

질문

* 표준프레임워크 실행환경 v3.0 , 3.1 , 3.5 , 3.6 환경에서 시큐리티 간소화 서비스 사용하는 경우.
* 시큐리티 간소화 서비스 기반에서 CSRF 보안취약점 대응 방법 안내.
* CSRF(Cross-Site Request Forgery, 사이트 간 요청 위조)는 로그인된 사용자의 브라우저를 이용해 사용자가 의도하지 않은 요청(등록·수정·삭제 등)을 서버에 전송시키는 공격이며, 서버가 발급한 일회성 토큰을 요청마다 검증하는 방식으로 방어.

답변

표준프레임워크 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 기반 설정 간소화 사용 시)
  - 세션이 새로 생성되면 토큰도 재발급되므로 페이지마다 서버가 렌더링한 최신 토큰을 사용해야 합니다.
 

이 페이지의 구성

자주 묻는 질문