2014-11-12 1 views
1

JSF-Spring 통합 애플리케이션이 있습니다. 스프링 보안 또한이 애플리케이션에 통합되어있다. 이 내 응용 프로그램의 버전은 다음과 같습니다JSF-Spring 통합 애플리케이션에서 CSRF 보호를 활성화하는 방법

  • JSF 2.2
  • 봄 4.0.3.RELEASE
  • 봄 보안 3.2.4.RELEASE JSF doc 모든 POST 요청에서 당으로

JSF2.x [또는 이전 버전]은 CSRF로 보호됩니다. 그러나 CSRF 공격으로 애플리케이션에 침투 할 수 있습니다.

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

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

Spring Security CSRF protection으로 시도해 볼 수 있습니다. 이 경우 문제는 모든 POST 케이스에서 코드를 편집해야한다는 것입니다.

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

Pinata으로 테스트하고 있습니다.

+0

[OWASP_CSRFGuard_Project] (https://www.owasp.org/index.php/Category:OWASP_CSRFGuard_Project)를 사용하여 CSRF 보호 기능을 구현했습니다. 이 접근법은 코드 변경을 추가하지 않는 유연성을 제공합니다. – Sam

+0

"코드 변경 방지"라고 쓰면 JSF 코드가 포함되어 있습니까? 아니면 자바 코드 만 의미합니까? –

+0

관련된 최소한의 수정은 [양식 요소 수정] (http://stackoverflow.com/questions/38931444/add-csrf-token-to-all-the-form-submissions)입니다. AJAX에 관해서는 ajax.settings presend에 추가해야합니다. – TecHunter

답변

1

스프링 4.3.7 및 스프링 시큐리티 4.2.2로 테스트되었습니다.

응용 프로그램의 form에 CSRF 토큰을 추가해야합니다. Any PATCH, POST, PUT and DELETE은 스프링 보안 (기본 동사의 경우)으로 보호됩니다. faces-config.xml에 설정하여 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); 
    } 
} 

을 : 수동으로 제공된 하나의 상단에 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에서 직접 토큰을 검색 할 수 있습니다.

+0

JSF AJAX에서 CSRF를 어떻게 추가합니까? – Ameya

+0

@ameya 요청 헤더에 추가해야합니다. 양식 입력에서 토큰 값을 가져올 수 있습니다. DOM 요소에있는 서버의 토큰과 함께 숨겨진 입력이 필요하므로 가져올 수 있습니다. 귀하의 페이지를 검사하면 입력란에 토큰을 찾을 수 있습니다 – TecHunter

+0

@Ameya 제발 또 다른 질문을 만듭니다. 어떤 경우 에든, 토큰에 대한 Spring 점검이 어떤 것이 등록되어 있는지 확인하는 데 도움이 될 때 중단 점을 추가하십시오. – TecHunter