복붙노트

[SPRING] JSF-Spring 통합 애플리케이션에서 CSRF 보호를 사용하는 방법

SPRING

JSF-Spring 통합 애플리케이션에서 CSRF 보호를 사용하는 방법

JSF-Spring 통합 응용 프로그램이 있습니다. 스프링 보안 또한이 애플리케이션에 통합되어있다. 내 응용 프로그램의 버전은 다음과 같습니다.

JSF 문서에 따라 JSF2.x [또는 이전 버전]의 모든 POST 요청은 CSRF로 보호됩니다. 그러나 CSRF 공격으로 애플리케이션에 침투 할 수 있습니다.

나는 다른 JSF2.2 [no Spring] 예제 애플리케이션을 시도했는데,이 경우 애플리케이션이 CSRF로 보호된다는 것을 알 수있다.

제 이해는 JSF / Spring / Spring 보안 조합이 원래 응용 프로그램에서 문제가되고 있다는 것입니다. 불행히도 로그 파일에는 도움이되는 정보가 없습니다.

스프링 보안 CSRF 보호를 시도 할 수 있습니다. 이 경우 문제는 모든 POST 케이스에서 코드를 편집해야한다는 것입니다.

이 코드 변경을 피하기 위해 JSF CSRF 보호 기능을 활성화하고자합니다. 어떠한 제안?

나는 Pinata로 시험하고있다.

해결법

  1. ==============================

    1.Spring 4.3.7 및 Spring Security 4.2.2로 테스트되었습니다.

    Spring 4.3.7 및 Spring Security 4.2.2로 테스트되었습니다.

    애플리케이션의 모든 양식에 CSRF 토큰을 추가해야합니다. 모든 PATCH, POST, PUT 및 DELETE는 Spring 보안 (기본 verb의 경우)에 의해 보호됩니다. 모든 양식에 숨겨진 입력을 수동으로 삽입하지 않으려면 제공된 양식 위에 FormRenderer를 만들 수 있습니다.

    import com.sun.faces.renderkit.html_basic.FormRenderer;
    
    import javax.el.ELContext;
    import javax.el.ExpressionFactory;
    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.context.ResponseWriter;
    import java.io.IOException;
    
    public class FormWithCSRFRenderer extends FormRenderer {
    
        @Override
        public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
            log.debug("FormWithCSRFRenderer - Adding CSRF Token to form element");
            ELContext elContext = context.getELContext();
            ExpressionFactory expFactory = context.getApplication().getExpressionFactory();
    
            ResponseWriter writer = context.getResponseWriter();
            writer.startElement("input", component);
            writer.writeAttribute("type", "hidden", null);
            writer.writeAttribute("name", expFactory.createValueExpression(elContext, "${_csrf.parameterName}", String.class).getValue(elContext), null);
            writer.writeAttribute("value", expFactory.createValueExpression(elContext, "${_csrf.token}", String.class).getValue(elContext), null);
            writer.endElement("input");
            writer.write("\n");
            super.encodeEnd(context, component);
        }
    }
    

    그런 다음 faces-config.xml에 설정하여 FormRenderer를 재정의합니다.

    <?xml version="1.0" encoding="UTF-8"?>
    <faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
                  version="2.2">
        <render-kit>
            <renderer>
                <component-family>javax.faces.Form</component-family>
                <renderer-type>javax.faces.Form</renderer-type>
                <renderer-class>com.acme.FormWithCSRFRenderer</renderer-class>
            </renderer>
        </render-kit>
    </faces-config>
    

    또한 스프링 컨텍스트에서 CSRF를 활성화하는 것을 잊지 마십시오.

    <security:http auto-config="true" entry-point-ref="preAuthenticatedProcessingFilterEntryPoint"
                   use-expressions="true">
        <security:csrf/>
        <security:access-denied-handler error-page="/exception/accessDenied.xhtml"/>
    
        <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_ADMINISTRATOR','ROLE_GUEST')"/>
        <security:intercept-url pattern="/exception/accessDenied.xhtml" access="permitAll"/>
    </security:http>
    

    AJAX 호출의 경우 보호 된 HTTP Verb의 데이터에이 토큰을 추가해야합니다. DOM에서 직접 토큰을 검색 할 수 있습니다.

  2. from https://stackoverflow.com/questions/26886121/how-to-enable-csrf-protection-in-jsf-spring-integrated-application by cc-by-sa and MIT license