如何在Java Web Apps的每个请求中应用反CSRF令牌?

时间:2018-12-14 11:13:57

标签: javascript java html web

我正在制作Java Web App。这项技术非常新。我需要在每个服务器请求中实现反CSRF令牌,以便可以使请求成为CSRF攻击安全的对象。我遇到了以下链接:

https://dzone.com/articles/preventing-csrf-java-web-apps

因此,在执行此操作的同时,我创建了如下代码:

LoadSalt.java

public void doFilter(final ServletRequest req,final ServletResponse res,
    final FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    response.addHeader("Access-Control-Allow-Origin","*");
    response.addHeader("Allow-Access-Control-Credentials", "true");
    response.addHeader("Access-Control-Allow-Methods","POST");
    response.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
    response.addHeader("Access-Control-Max-Age", "1728000");
    response.addHeader("X-Content-Type-Options", "nosniff");
    response.addHeader("X-XSS-Protection", "1; mode=block"); // on
    response.addHeader("X-Frame-Options", "deny");
    response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate, private"); // HTTP 1.1.
    response.addHeader("Pragma", "no-cache"); // HTTP 1.0.
    response.addDateHeader("Expires", 0); // Proxies.

    System.out.println(request.getRequestURL());

    // Check the user session for the salt cache, if none is present we create one
    @SuppressWarnings("unchecked")
    Cache<String, Boolean> csrfPreventionSaltCache = (Cache<String, Boolean>) request.getSession().getAttribute("csrfPreventionSaltCache");

    if (csrfPreventionSaltCache == null)
    {
        csrfPreventionSaltCache = CacheBuilder.newBuilder().maximumSize(5000).expireAfterWrite(20, TimeUnit.MINUTES).build();
        request.getSession().setAttribute("csrfPreventionSaltCache", csrfPreventionSaltCache);
    }

    // Generate the salt and store it in the users cache
    String salt = RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom());
    csrfPreventionSaltCache.put(salt, Boolean.TRUE);
    // Add the salt to the current request so it can be used
    // by the page rendered in this request
    request.setAttribute("csrfPreventionSalt", salt);
    filterChain.doFilter(request, response);
    }

ValidateSalt.java

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

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

    // Get the salt sent with the request
    String salt = (String) httpReq.getAttribute("csrfPreventionSalt");

    // Validate that the salt is in the cache
    @SuppressWarnings("unchecked")
    Cache<String, Boolean> csrfPreventionSaltCache = (Cache<String, Boolean>) httpReq.getSession().getAttribute("csrfPreventionSaltCache");
    if (csrfPreventionSaltCache != null && salt != null && csrfPreventionSaltCache.getIfPresent(salt) != null)
    {
        // If the salt 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!! Inform a scary sysadmin ASAP.");
    }
}

在web.xml中添加了过滤器

<filter>
     <filter-name>LoadSalt</filter-name>
     <filter-class>com.sample.filter.LoadSalt</filter-class>
 </filter>
  <filter-mapping>
     <filter-name>LoadSalt</filter-name>
     <url-pattern>/*</url-pattern>
  </filter-mapping>


  <filter>
     <display-name>ValidateSalt</display-name>
     <filter-name>ValidateSalt</filter-name>
     <filter-class>com.sample.filter.ValidateSalt</filter-class>
  </filter>
  <filter-mapping>
     <filter-name>ValidateSalt</filter-name>
     <servlet-name>ControllerServlet</servlet-name>
  </filter-mapping>

问题在于,执行请求时,它不会失败。它总是创建一个新的“盐”值。理想情况下,它应该会失败,因为我没有在任何JSP页面中以HTML形式编写以下代码(如上面共享的链接中所述):

<form action="/transferMoneyServlet" method="get">
<input type="hidden" name="csrfPreventionSalt" value="<c:out 
value='${csrfPreventionSalt}'/>"/>
 ...
 </form>

有人,请帮助我。预先感谢。

0 个答案:

没有答案