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

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

본문 영역

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

자주 묻는 질문

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

    관리자

  • 작성일자

    2026-08-14

  • 조회수

    80

질문

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

답변

표준프레임워크 v3.0 ~ v3.6(Spring Security 설정 간소화) 환경에서 CSRF 방어를 적용하는 방법을 안내 드립니다.

■ 배경
표준프레임워크 v3.0 ~ v3.6 환경에서 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 기반 설정 간소화 사용 시)
  - 세션이 새로 생성되면 토큰도 재발급되므로 페이지마다 서버가 렌더링한 최신 토큰을 사용해야 합니다.
  - 표준프레임워크 v3.7 이상에서 시큐리티 간소화 사용시에는 csrf 옵션을 활성화 하면 됩니다. ( csrf="true" )
https://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte3:fdl:server_security:xmlschema_v3_7
 

이 페이지의 구성

자주 묻는 질문