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 |