1

Hello,
I am trying to prevent my web application from CSRF. I followed this link
Link for https://dzone.com/articles/preventing-csrf-java-web-apps.To implement this mechanism in Java I choose to use two filters, one to create the token/salt for each request, and another to validate it. Since the users request and subsequent POST or GETs that should be validated do not necessarily get executed in order, I decided to use a time based cache to store a list of valid salt strings. The first filter, used to generate a new token for a request and store it in the cache.I am getting the token value in validateetoken as null. Can you please let me know whats incorrect. The logs from my console are :

Checking cache befor creating it from Request :csrfPreventionCache: null
After setting the csrfPreventionCache to HttpReq
--------csrfPreventionCache------ :com.google.common.cache.LocalCache$LocalManualCache@254e3d6
Before going to validate token checking for token in request
 httpReq.getAttribute(csrfToken) ----:DsJiKiGq9BTrLOtA2SzgSYuEnlD
I am in ValidateToken : csrfToken: null
csrfPreventionCache is  com.google.common.cache.LocalCache$LocalManualCache@254e3d6
<Sep 26, 2017 12:21:38 PM EDT> <Error> <HTTP> <BEA-101020> <[ServletContext@2065349032[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 Answer 1

1

Please use HttpSession to add the attribute as you have to use the csrfToken in different request.

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

     HttpSession session=request.getSession(false);  // in ValidateCSRFToken
     String csrfToken=(String)session.getAttribute("csrfToken"); 
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot. I am able to retrieve the value setting in the session.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.