File Source: securitytokenvalidator.java

         /* 
    P/P   *  Method: net.sourceforge.pebble.web.security.SecurityTokenValidator__static_init
          * 
          *  Postconditions:
          *    random == &new SecureRandom(SecurityTokenValidator__static_init#1)
          *    new SecureRandom(SecurityTokenValidator__static_init#1) num objects == 1
          */
     1  /*
     2   * Copyright (c) 2003-2005, Simon Brown
     3   * All rights reserved.
     4   *
     5   * Redistribution and use in source and binary forms, with or without
     6   * modification, are permitted provided that the following conditions are met:
     7   *
     8   *   - Redistributions of source code must retain the above copyright
     9   *     notice, this list of conditions and the following disclaimer.
    10   *
    11   *   - Redistributions in binary form must reproduce the above copyright
    12   *     notice, this list of conditions and the following disclaimer in
    13   *     the documentation and/or other materials provided with the
    14   *     distribution.
    15   *
    16   *   - Neither the name of Pebble nor the names of its contributors may
    17   *     be used to endorse or promote products derived from this software
    18   *     without specific prior written permission.
    19   *
    20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    30   * POSSIBILITY OF SUCH DAMAGE.
    31   */
    32  package net.sourceforge.pebble.web.security;
    33  
    34  import net.sourceforge.pebble.web.action.Action;
    35  
         /* 
    P/P   *  Method: void net.sourceforge.pebble.web.security.SecurityTokenValidator()
          */
    36  import javax.servlet.http.Cookie;
    37  import javax.servlet.http.HttpServletRequest;
    38  import javax.servlet.http.HttpServletResponse;
    39  import java.security.SecureRandom;
    40  
    41  /**
    42   * Checks requests for a security token
    43   *
    44   * @author James Roper
    45   */
    46  public class SecurityTokenValidator {
    47  
    48    /**
    49     * the security token name
    50     */
    51    public static final String PEBBLE_SECURITY_TOKEN_PARAMETER = "pebbleSecurityToken";
    52  
    53    /**
    54     * the header for bypassing security token checks
    55     */
    56    private static final String PEBBLE_SECURITY_TOKEN_HEADER = "X-Pebble-Token";
    57  
    58    /**
    59     * the value the header should be for not checking
    60     */
    61    private static final String PEBBLE_SECURITY_TOKEN_HEADER_NOCHECK = "nocheck";
    62  
    63    /**
    64     * For generating secure tokens
    65     */
    66    private static final SecureRandom random = new SecureRandom();
    67  
    68    /**
    69     * Validate the security token for this request, if necessary, setting up the security token cookie if it doesn't
    70     * exist
    71     *
    72     * @param request The request to validate
    73     * @param response The response
    74     * @param action The action to validate
    75     * @return true if the request can proceed, false if not
    76     */
    77    public boolean validateSecurityToken(HttpServletRequest request, HttpServletResponse response, Action action) {
    78      // First, ensure that there is a security token, for future requests
             /* 
    P/P       *  Method: bool validateSecurityToken(HttpServletRequest, HttpServletResponse, Action)
              * 
              *  Preconditions:
              *    action != null
              *    (soft) request != null
              * 
              *  Presumptions:
              *    ensureSecurityTokenExists(...)@79 != null
              * 
              *  Postconditions:
              *    init'ed(return_value)
              * 
              *  Test Vectors:
              *    java.lang.String:equals(...)@83: {0}, {1}
              */
    79      String token = ensureSecurityTokenExists(request, response);
    80      if (shouldValidate(action, request)) {
    81        // Check for the header is there... XSRF attacks can't set custom headers, so if this header is there,
    82        // it must be safe
    83        if (PEBBLE_SECURITY_TOKEN_HEADER_NOCHECK.equals(request.getHeader(PEBBLE_SECURITY_TOKEN_HEADER))) {
    84          return true;
    85        }
    86        // We must validate the token
    87        String requestToken = request.getParameter(PEBBLE_SECURITY_TOKEN_PARAMETER);
    88        // Compare token to cookie
    89        return token.equals(requestToken);
    90      } else {
    91        return true;
    92      }
    93    }
    94  
    95    private boolean shouldValidate(Action action, HttpServletRequest request)
    96    {
             /* 
    P/P       *  Method: bool shouldValidate(Action, HttpServletRequest)
              * 
              *  Preconditions:
              *    action != null
              * 
              *  Presumptions:
              *    java.lang.Object:getClass(...)@97 != null
              * 
              *  Postconditions:
              *    init'ed(return_value)
              * 
              *  Test Vectors:
              *    java.lang.Class:getAnnotation(...)@97: Addr_Set{null}, Inverse{null}
              */
    97      RequireSecurityToken annotation = action.getClass().getAnnotation(RequireSecurityToken.class);
    98      if (annotation != null) {
    99        // Check for a condition
   100        Class<? extends SecurityTokenValidatorCondition> condition = annotation.value();
   101        if (condition != null && condition != NullSecurityTokenValidatorCondition.class) {
   102          // Instantiate condition
   103          try {
   104            return condition.newInstance().shouldValidate(request);
   105          } catch (IllegalAccessException iae) {
   106            throw new RuntimeException("Could not instantiate " + condition);
   107          } catch (InstantiationException ie) {
   108            throw new RuntimeException("Could not instantiate " + condition);
   109          }
   110        }
   111        // Otherwise, with no condition we should return validate
   112        return true;
   113      } else {
   114        // We have no annotation, don't validate
   115        return false;
   116      }
   117    }
   118  
   119    private String ensureSecurityTokenExists(HttpServletRequest request, HttpServletResponse response) {
   120      String token = (String) request.getAttribute(PEBBLE_SECURITY_TOKEN_PARAMETER);
   121      if (token != null) {
   122        // We've already configured it for this request
   123        return token;
   124      }
   125      String contextPath = request.getContextPath();
   126      Cookie[] cookies = request.getCookies();
   127      if (cookies != null) {
   128        for (Cookie cookie : cookies) {
   129          if (PEBBLE_SECURITY_TOKEN_PARAMETER.equals(cookie.getName())) {
   130            if (contextPath != null && contextPath.length() > 0) {
   131              if (contextPath.equals(cookie.getPath())) {
   132                token = cookie.getValue();
   133                break;
   134              }
   135            } else {
   136              token = cookie.getValue();
   137              break;
   138            }
   139          }
   140        }
   141      }
   142      // No cookie, generate a token at least 12 characters long
   143      if (token == null) {
   144        token = "";
   145        while (token.length() < 12) {
   146          token += Long.toHexString(random.nextLong());
   147        }
   148        // Set the cookie
   149        Cookie cookie = new Cookie(PEBBLE_SECURITY_TOKEN_PARAMETER, token);
   150        // Non persistent
   151        cookie.setMaxAge(-1);
   152        cookie.setPath(contextPath);
   153        response.addCookie(cookie);
   154      }
   155      // Set it as a request attribute so the security token tag can find it
   156      request.setAttribute(PEBBLE_SECURITY_TOKEN_PARAMETER, token);
   157      return token;
   158    }
   159    
   160  }








SofCheck Inspector Build Version : 2.22510
securitytokenvalidator.java 2010-Jun-25 19:40:32
securitytokenvalidator.class 2010-Jul-19 20:23:38