2017-09-26 16 views
0

こんにちは、
私のWebアプリケーションがCSRFから保護されないようにしようとしています。私はこのリンクに従いました
https://dzone.com/articles/preventing-csrf-java-web-apps.Toのリンクは、このメカニズムをJavaで実装します。リクエストごとにトークン/ソルトを作成するフィルタと、それを検証するフィルタという2つのフィルタを使用することを選択しました。ユーザーの要求とそれに続くPOSTまたはGETの検証は必ずしも順番に実行されるとは限らないため、有効な塩ストリングのリストを格納するために時間ベースのキャッシュを使用することに決めました。要求の新しいトークンを生成してキャッシュに格納するために使用される最初のフィルタ。validateetokenのトークン値をnullとして取得しています。私は何が間違っているか教えてください。私のコンソールからのログは、次のとおりです。あなたが別のリクエストでcsrfToken を使用する必要がありますようJavaアプリケーションでCSRFを実装する際にエラーが発生しました

Checking cache befor creating it from Request :csrfPreventionCache: null 
After setting the csrfPreventionCache to HttpReq 
--------csrfPreventionCache------ :[email protected] 
Before going to validate token checking for token in request 
httpReq.getAttribute(csrfToken) ----:DsJiKiGq9BTrLOtA2SzgSYuEnlD 
I am in ValidateToken : csrfToken: null 
csrfPreventionCache is [email protected] 
<Sep 26, 2017 12:21:38 PM EDT> <Error> <HTTP> <BEA-101020> <[[email protected][app:common module:commonWebApp path:null spec-version:3.1]] Servlet failed with an Exception 
java.lang.NullPointerException 
    at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:191) 
    at com.google.common.cache.LocalCache.getIfPresent(LocalCache.java:3988) 
    at com.google.common.cache.LocalCache$LocalManualCache.getIfPresent(LocalCache.java:4783) 
    at com.freddiemac.msof.fire.common.ui.report.actions.ValidateCSRFToken.doFilter(ValidateCSRFToken.java:37) 
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78) 
    Truncated. see log file for complete stacktrace 


    CSRFToken.java  
     package com.test.fire.common.ui.report.actions; 

     import java.io.IOException; 
     import java.util.Random; 
     import java.util.concurrent.TimeUnit; 

     import javax.servlet.Filter; 
     import javax.servlet.FilterChain; 
     import javax.servlet.FilterConfig; 
     import javax.servlet.ServletException; 
     import javax.servlet.ServletRequest; 
     import javax.servlet.ServletResponse; 
     import javax.servlet.http.HttpServletRequest; 

     import org.apache.commons.lang.RandomStringUtils; 

     import com.google.common.cache.Cache; 
     import com.google.common.cache.CacheBuilder; 

     public class CSRFToken implements Filter{ 

      @SuppressWarnings("unchecked") 
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
       // Assuming, its HTTP 
       HttpServletRequest httpReq = (HttpServletRequest) request; 

       // Check the user session for the cache, if none is present we create one 
       Cache<String, Boolean> csrfPreventionCache = (Cache<String, Boolean>) httpReq.getSession().getAttribute("csrfPreventionCache"); 
       System.out.println("Checking cache befor creating it from Request :csrfPreventionCache: "+csrfPreventionCache); 

       if (csrfPreventionCache == null){ 
        csrfPreventionCache = CacheBuilder.newBuilder() 
          .maximumSize(5000) 
          .expireAfterWrite(20, TimeUnit.MINUTES) 
          .build(); 
        httpReq.getSession().setAttribute("csrfPreventionCache", csrfPreventionCache); 
        System.out.println("After setting the csrfPreventionCache to HttpReq"); 
        System.out.println("--------csrfPreventionCache------ :"+httpReq.getSession().getAttribute("csrfPreventionCache")); 
       } 
       // Generate the csrfToken and store it in the users cache 
       String csrfToken = RandomStringUtils.random(27, 0, 0, true, true, null, new Random()); 
       csrfPreventionCache.put(csrfToken, Boolean.TRUE); 

       // Add the token to the current request so it can be used by the page rendered in this request 
       httpReq.setAttribute("csrfToken", csrfToken); 
       System.out.println("Before going to validate token checking for token in request"); 
       System.out.println(" httpReq.getAttribute(csrfToken) ----:"+httpReq.getAttribute("csrfToken")); 
       chain.doFilter(request, response); 
      } 

      public void init(FilterConfig filterConfig) throws ServletException { 
      //Do Nothing 
      } 

      public void destroy() { 
      //Do Nothing 
      } 

     } 




    Mapping in web.xml 

      <servlet-mapping> 
     <servlet-name>action</servlet-name> 
     <url-pattern>*.do</url-pattern> 
     </servlet-mapping> 
      <filter> 
      <filter-name>csrfToken</filter-name> 
      <filter-class>com.test.fire.common.ui.report.actions.CSRFToken</filter-class> 
     </filter> 
     <filter-mapping> 
      <filter-name>csrfToken</filter-name> 
      <url-pattern>*.do</url-pattern> 
     </filter-mapping> 
     <filter> 
     <filter-name>validateCSRFToken</filter-name> 
     <filter-class>com.test.fire.common.ui.report.actions.ValidateCSRFToken</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>validateCSRFToken</filter-name> 
     <url-pattern>*.do</url-pattern> 
    </filter-mapping> 





     ValidateToken 

     package com.test.msof.fire.common.ui.report.actions; 

    import java.io.IOException; 
    import java.util.Random; 
    import java.util.concurrent.TimeUnit; 

    import javax.servlet.Filter; 
    import javax.servlet.FilterChain; 
    import javax.servlet.FilterConfig; 
    import javax.servlet.ServletException; 
    import javax.servlet.ServletRequest; 
    import javax.servlet.ServletResponse; 
    import javax.servlet.http.HttpServletRequest; 

    import org.apache.commons.lang.RandomStringUtils; 

    import com.google.common.cache.Cache; 
    import com.google.common.cache.CacheBuilder; 

    public class ValidateCSRFToken implements Filter{ 

     @Override 
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException { 

      // Assume its HTTP 
      HttpServletRequest httpReq = (HttpServletRequest) request; 

      // Get the token sent with the request 
      String csrfToken = (String) httpReq.getParameter("csrfToken"); 
      System.out.println("I am in ValidateToken : csrfToken: "+csrfToken); 

      // Validate that the token is in the cache 
      Cache<String, Boolean> csrfPreventionCache = (Cache<String, Boolean>) 
       httpReq.getSession().getAttribute("csrfPreventionCache"); 
      System.out.println("csrfPreventionCache is "+csrfPreventionCache); 
      System.out.println("csrfPreventionCache.getIfPresent(csrfToken) is "+csrfPreventionCache.getIfPresent(csrfToken)); 

      if (csrfPreventionCache != null && 
        csrfToken != null && 
        csrfPreventionCache.getIfPresent(csrfToken) != null){ 

       // If the token is in the cache, we move on 
       chain.doFilter(request, response); 
      } else { 
       // Otherwise we throw an exception aborting the request flow 
       throw new ServletException("Potential CSRF detected!!."); 
      } 
     } 

     @Override 
     public void init(FilterConfig arg0) throws ServletException { 
     } 

     @Override 
     public void destroy() { 
     } 
    } 




    jsp - Added the below entry as a hidden variable 



<%@ page info="reportBody"%> 

    <%@ taglib uri="/tags/struts-bean" prefix="bean" %> 
    <%@ taglib uri="/tags/struts-logic" prefix="logic" %> 
    <%@ taglib uri="/tags/struts-html" prefix="html" %> 



    <%--<table background="/vaeWebApp/images/a1.gif" border="0" cellspacing="0" cellpadding="0" width="100%" height="100%"> --%> 
    <table border="0" cellspacing="0" cellpadding="0" width="100%" height="100%"> 
    <logic:iterate id="appListForm" 
      name="appReportHomeForm" 
      property="appListForms" 
      indexId="contIndex" 
      type="com.freddiemac.msof.fire.common.ui.report.forms.AppListForm" 
      > 
     <% 
      String ind = "appListForms["+contIndex+"]."; 
      System.out.println("ind:" + ind); 
      <input type="hidden" name="csrfToken" value="<c:out value='${csrfToken}'/>"/> 
     %> 
     <tr> 
      <td> 
        <u><h2> 
        <html:link href="appReportListHome.do" name="appReportHomeForm" property='<%= ind+"parameters" %>'> 
        <bean:write name="appReportHomeForm" property='<%= ind+"appDesc" %>' /> 
        </html:link> 
        </h2></u> 
      </td> 


     </tr> 
     <tr> 
     <td> 
    <p> 
     <%-- {Describe more about specific report here} --%> 
    </p> 
     </td 
    </tr> 
    </logic:iterate> 



     </td 
    </tr> 

    </table> 

答えて

1

は、属性を追加するためのHttpSessionを使用してください。

 HttpSession session=request.getSession(); //in CSRFToken class 
    session.setAttribute("csrfToken",csrfToken); 

    HttpSession session=request.getSession(false); // in ValidateCSRFToken 
    String csrfToken=(String)session.getAttribute("csrfToken"); 
+0

ありがとうございました。私は、セッションの値の設定を取得することができます。 –

関連する問題