Author: markt Date: Thu Jun 24 09:57:02 2010 New Revision: 957478 URL: http://svn.apache.org/viewvc?rev=957478&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49476 CSRF protection was preventing access to session expiration features Also: - Switch Manager app to generic CSRF protection - Add support for multiple nonces to CSRF filter - Improve 403 page - Don't open JSP pages in session expiration in a new window - makes CSRF prevention a real pain
Modified: tomcat/trunk/java/org/apache/catalina/filters/CsrfPreventionFilter.java tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties tomcat/trunk/webapps/docs/config/filter.xml tomcat/trunk/webapps/manager/403.jsp tomcat/trunk/webapps/manager/WEB-INF/jsp/sessionDetail.jsp tomcat/trunk/webapps/manager/WEB-INF/jsp/sessionsList.jsp tomcat/trunk/webapps/manager/WEB-INF/web.xml Modified: tomcat/trunk/java/org/apache/catalina/filters/CsrfPreventionFilter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/CsrfPreventionFilter.java?rev=957478&r1=957477&r2=957478&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/filters/CsrfPreventionFilter.java (original) +++ tomcat/trunk/java/org/apache/catalina/filters/CsrfPreventionFilter.java Thu Jun 24 09:57:02 2010 @@ -19,6 +19,8 @@ package org.apache.catalina.filters; import java.io.IOException; import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Random; import java.util.Set; @@ -51,6 +53,8 @@ public class CsrfPreventionFilter extend private final Random randomSource = new Random(); private final Set<String> entryPoints = new HashSet<String>(); + + private final int nonceCacheSize = 5; @Override protected Log getLogger() { @@ -98,24 +102,30 @@ public class CsrfPreventionFilter extend } } + @SuppressWarnings("unchecked") + LruCache<String> nonceCache = + (LruCache<String>) req.getSession(true).getAttribute( + Constants.CSRF_NONCE_SESSION_ATTR_NAME); + if (!skipNonceCheck) { String previousNonce = req.getParameter(Constants.CSRF_NONCE_REQUEST_PARAM); - String expectedNonce = - (String) req.getSession(true).getAttribute( - Constants.CSRF_NONCE_SESSION_ATTR_NAME); - - if (expectedNonce != null && - !expectedNonce.equals(previousNonce)) { + + if (nonceCache != null && !nonceCache.contains(previousNonce)) { res.sendError(HttpServletResponse.SC_FORBIDDEN); return; } } + if (nonceCache == null) { + nonceCache = new LruCache<String>(nonceCacheSize); + req.getSession().setAttribute( + Constants.CSRF_NONCE_SESSION_ATTR_NAME, nonceCache); + } + String newNonce = generateNonce(); - req.getSession(true).setAttribute( - Constants.CSRF_NONCE_SESSION_ATTR_NAME, newNonce); + nonceCache.add(newNonce); wResponse = new CsrfResponseWrapper(res, newNonce); } else { @@ -225,4 +235,32 @@ public class CsrfPreventionFilter extend return (sb.toString()); } } + + private static class LruCache<T> { + + // Although the internal implementation uses a Map, this cache + // implementation is only concerned with the keys. + private final Map<T,T> cache; + + public LruCache(final int cacheSize) { + cache = new LinkedHashMap<T,T>() { + private static final long serialVersionUID = 1L; + @Override + protected boolean removeEldestEntry(Map.Entry<T,T> eldest) { + if (size() > cacheSize) { + return true; + } + return false; + } + }; + } + + public void add(T key) { + cache.put(key, null); + } + + public boolean contains(T key) { + return cache.containsKey(key); + } + } } Modified: tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java?rev=957478&r1=957477&r2=957478&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java (original) +++ tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java Thu Jun 24 09:57:02 2010 @@ -84,10 +84,6 @@ public final class HTMLManagerServlet ex protected static final String APPLICATION_MESSAGE = "message"; protected static final String APPLICATION_ERROR = "error"; - protected static final String NONCE_SESSION = - "org.apache.catalina.manager.NONCE"; - protected static final String NONCE_REQUEST = "nonce"; - protected static final String sessionsListJspPath = "/WEB-INF/jsp/sessionsList.jsp"; protected static final String sessionDetailJspPath = "/WEB-INF/jsp/sessionDetail.jsp"; @@ -177,31 +173,12 @@ public final class HTMLManagerServlet ex String deployPath = request.getParameter("deployPath"); String deployConfig = request.getParameter("deployConfig"); String deployWar = request.getParameter("deployWar"); - String requestNonce = request.getParameter(NONCE_REQUEST); // Prepare our output writer to generate the response message response.setContentType("text/html; charset=" + Constants.CHARSET); String message = ""; - // Check nonce - // There *must* be a nonce in the session before any POST is processed - HttpSession session = request.getSession(); - String sessionNonce = (String) session.getAttribute(NONCE_SESSION); - if (sessionNonce == null) { - message = sm.getString("htmlManagerServlet.noNonce", command); - // Reset the command - command = null; - } else { - if (!sessionNonce.equals(requestNonce)) { - // Nonce mis-match. - message = - sm.getString("htmlManagerServlet.nonceMismatch", command); - // Reset the command - command = null; - } - } - if (command == null || command.length() == 0) { // No command == list // List always displayed -> do nothing @@ -417,9 +394,6 @@ public final class HTMLManagerServlet ex log("list: Listing contexts for virtual host '" + host.getName() + "'"); - String newNonce = generateNonce(); - request.getSession().setAttribute(NONCE_SESSION, newNonce); - PrintWriter writer = response.getWriter(); // HTML Header Section @@ -509,12 +483,12 @@ public final class HTMLManagerServlet ex Map.Entry<String,String> entry = iterator.next(); String displayPath = entry.getKey(); String contextPath = entry.getValue(); - Context context = (Context) host.findChild(contextPath); + Context ctxt = (Context) host.findChild(contextPath); if (displayPath.equals("")) { displayPath = "/"; } - if (context != null ) { + if (ctxt != null ) { try { isDeployed = isDeployed(contextPath); } catch (Exception e) { @@ -525,17 +499,17 @@ public final class HTMLManagerServlet ex args = new Object[7]; args[0] = URL_ENCODER.encode(displayPath); args[1] = displayPath; - args[2] = context.getDisplayName(); + args[2] = ctxt.getDisplayName(); if (args[2] == null) { args[2] = " "; } - args[3] = new Boolean(context.getAvailable()); + args[3] = new Boolean(ctxt.getAvailable()); args[4] = response.encodeURL (request.getContextPath() + "/html/sessions?path=" + URL_ENCODER.encode(displayPath)); - if (context.getManager() != null) { + if (ctxt.getManager() != null) { args[5] = new Integer - (context.getManager().getActiveSessions()); + (ctxt.getManager().getActiveSessions()); } else { args[5] = new Integer(0); } @@ -545,7 +519,7 @@ public final class HTMLManagerServlet ex writer.print (MessageFormat.format(APPS_ROW_DETAILS_SECTION, args)); - args = new Object[15]; + args = new Object[14]; args[0] = response.encodeURL (request.getContextPath() + "/html/start?path=" + URL_ENCODER.encode(displayPath)); @@ -568,27 +542,26 @@ public final class HTMLManagerServlet ex "/html/expire?path=" + URL_ENCODER.encode(displayPath)); args[9] = appsExpire; args[10] = sm.getString("htmlManagerServlet.expire.explain"); - Manager manager = context.getManager(); + Manager manager = ctxt.getManager(); if (manager == null) { args[11] = sm.getString("htmlManagerServlet.noManager"); } else { args[11] = new Integer( - context.getManager().getMaxInactiveInterval()/60); + ctxt.getManager().getMaxInactiveInterval()/60); } args[12] = sm.getString("htmlManagerServlet.expire.unit"); args[13] = highlightColor; - args[14] = newNonce; - if (context.getPath().equals(this.context.getPath())) { + if (ctxt.getPath().equals(this.context.getPath())) { writer.print(MessageFormat.format( MANAGER_APP_ROW_BUTTON_SECTION, args)); - } else if (context.getAvailable() && isDeployed) { + } else if (ctxt.getAvailable() && isDeployed) { writer.print(MessageFormat.format( STARTED_DEPLOYED_APPS_ROW_BUTTON_SECTION, args)); - } else if (context.getAvailable() && !isDeployed) { + } else if (ctxt.getAvailable() && !isDeployed) { writer.print(MessageFormat.format( STARTED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION, args)); - } else if (!context.getAvailable() && isDeployed) { + } else if (!ctxt.getAvailable() && isDeployed) { writer.print(MessageFormat.format( STOPPED_DEPLOYED_APPS_ROW_BUTTON_SECTION, args)); } else { @@ -600,7 +573,7 @@ public final class HTMLManagerServlet ex } // Deploy Section - args = new Object[8]; + args = new Object[7]; args[0] = sm.getString("htmlManagerServlet.deployTitle"); args[1] = sm.getString("htmlManagerServlet.deployServer"); args[2] = response.encodeURL(request.getContextPath() + "/html/deploy"); @@ -608,26 +581,23 @@ public final class HTMLManagerServlet ex args[4] = sm.getString("htmlManagerServlet.deployConfig"); args[5] = sm.getString("htmlManagerServlet.deployWar"); args[6] = sm.getString("htmlManagerServlet.deployButton"); - args[7] = newNonce; writer.print(MessageFormat.format(DEPLOY_SECTION, args)); - args = new Object[5]; + args = new Object[4]; args[0] = sm.getString("htmlManagerServlet.deployUpload"); args[1] = response.encodeURL(request.getContextPath() + "/html/upload"); args[2] = sm.getString("htmlManagerServlet.deployUploadFile"); args[3] = sm.getString("htmlManagerServlet.deployButton"); - args[4] = newNonce; writer.print(MessageFormat.format(UPLOAD_SECTION, args)); // Diagnostics section - args = new Object[6]; + args = new Object[5]; args[0] = sm.getString("htmlManagerServlet.diagnosticsTitle"); args[1] = sm.getString("htmlManagerServlet.diagnosticsLeak"); args[2] = response.encodeURL( request.getContextPath() + "/html/findleaks"); - args[3] = newNonce; - args[4] = sm.getString("htmlManagerServlet.diagnosticsLeakWarning"); - args[5] = sm.getString("htmlManagerServlet.diagnosticsLeakButton"); + args[3] = sm.getString("htmlManagerServlet.diagnosticsLeakWarning"); + args[4] = sm.getString("htmlManagerServlet.diagnosticsLeakButton"); writer.print(MessageFormat.format(DIAGNOSTICS_SECTION, args)); // Server Header Section @@ -870,12 +840,12 @@ public final class HTMLManagerServlet ex String searchPath = path; if( path.equals("/") ) searchPath = ""; - Context context = (Context) host.findChild(searchPath); - if (null == context) { + Context ctxt = (Context) host.findChild(searchPath); + if (null == ctxt) { throw new IllegalArgumentException(sm.getString("managerServlet.noContext", RequestUtil.filter(path))); } - Session[] sessions = context.getManager().findSessions(); + Session[] sessions = ctxt.getManager().findSessions(); return sessions; } protected Session getSessionForPathAndId(String path, String id) throws IOException { @@ -886,12 +856,12 @@ public final class HTMLManagerServlet ex String searchPath = path; if( path.equals("/") ) searchPath = ""; - Context context = (Context) host.findChild(searchPath); - if (null == context) { + Context ctxt = (Context) host.findChild(searchPath); + if (null == ctxt) { throw new IllegalArgumentException(sm.getString("managerServlet.noContext", RequestUtil.filter(path))); } - Session session = context.getManager().findSession(id); + Session session = ctxt.getManager().findSession(id); return session; } @@ -955,7 +925,7 @@ public final class HTMLManagerServlet ex resp.setHeader("Cache-Control", "no-cache,no-store,max-age=0"); // HTTP 1.1 resp.setDateHeader("Expires", 0); // 0 means now req.setAttribute("currentSession", session); - getServletContext().getRequestDispatcher(sessionDetailJspPath).include(req, resp); + getServletContext().getRequestDispatcher(resp.encodeURL(sessionDetailJspPath)).include(req, resp); } /** @@ -1152,7 +1122,7 @@ public final class HTMLManagerServlet ex " <td class=\"row-left\" bgcolor=\"{6}\" rowspan=\"2\"><small>{2}</small></td>\n" + " <td class=\"row-center\" bgcolor=\"{6}\" rowspan=\"2\"><small>{3}</small></td>\n" + " <td class=\"row-center\" bgcolor=\"{6}\" rowspan=\"2\">" + - "<small><a href=\"{4}\" target=\"_blank\">{5}</a></small></td>\n"; + "<small><a href=\"{4}\">{5}</a></small></td>\n"; private static final String MANAGER_APP_ROW_BUTTON_SECTION = " <td class=\"row-left\" bgcolor=\"{13}\">\n" + @@ -1167,7 +1137,6 @@ public final class HTMLManagerServlet ex " <td class=\"row-left\" bgcolor=\"{13}\">\n" + " <form method=\"POST\" action=\"{8}\">\n" + " <small>\n" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\">" + " <input type=\"submit\" value=\"{9}\"> {10} <input type=\"text\" name=\"idle\" size=\"5\" value=\"{11}\"> {12} \n" + " </small>\n" + " </form>\n" + @@ -1178,15 +1147,12 @@ public final class HTMLManagerServlet ex " <td class=\"row-left\" bgcolor=\"{13}\">\n" + " <small>{1}</small> \n" + " <form class=\"inline\" method=\"POST\" action=\"{2}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\">" + " <small><input type=\"submit\" value=\"{3}\"></small>" + " </form>\n" + " <form class=\"inline\" method=\"POST\" action=\"{4}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\">" + " <small><input type=\"submit\" value=\"{5}\"></small>" + " </form>\n" + " <form class=\"inline\" method=\"POST\" action=\"{6}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" + " <small><input type=\"submit\" value=\"{7}\"></small>" + " </form>\n" + " </td>\n" + @@ -1194,7 +1160,6 @@ public final class HTMLManagerServlet ex " <td class=\"row-left\" bgcolor=\"{13}\">\n" + " <form method=\"POST\" action=\"{8}\">\n" + " <small>\n" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\">" + " <input type=\"submit\" value=\"{9}\"> {10} <input type=\"text\" name=\"idle\" size=\"5\" value=\"{11}\"> {12} \n" + " </small>\n" + " </form>\n" + @@ -1204,13 +1169,11 @@ public final class HTMLManagerServlet ex private static final String STOPPED_DEPLOYED_APPS_ROW_BUTTON_SECTION = " <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" + " <form class=\"inline\" method=\"POST\" action=\"{0}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\">" + " <small><input type=\"submit\" value=\"{1}\"></small>" + " </form>\n" + " <small>{3}</small> \n" + " <small>{5}</small> \n" + " <form class=\"inline\" method=\"POST\" action=\"{6}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\">" + " <small><input type=\"submit\" value=\"{7}\"></small>" + " </form>\n" + " </td>\n" + @@ -1220,11 +1183,9 @@ public final class HTMLManagerServlet ex " <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" + " <small>{1}</small> \n" + " <form class=\"inline\" method=\"POST\" action=\"{2}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\">" + " <small><input type=\"submit\" value=\"{3}\"></small>" + " </form>\n" + " <form class=\"inline\" method=\"POST\" action=\"{4}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\">" + " <small><input type=\"submit\" value=\"{5}\"></small>" + " </form>\n" + " <small>{7}</small> \n" + @@ -1234,7 +1195,6 @@ public final class HTMLManagerServlet ex private static final String STOPPED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION = " <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" + " <form class=\"inline\" method=\"POST\" action=\"{0}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\">" + " <small><input type=\"submit\" value=\"{1}\"></small>" + " </form>\n" + " <small>{3}</small> \n" + @@ -1256,7 +1216,6 @@ public final class HTMLManagerServlet ex "<tr>\n" + " <td colspan=\"2\">\n" + "<form method=\"post\" action=\"{2}\">\n" + - "<input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{7}\" >" + "<table cellspacing=\"0\" cellpadding=\"3\">\n" + "<tr>\n" + " <td class=\"row-right\">\n" + @@ -1303,7 +1262,6 @@ public final class HTMLManagerServlet ex " <td colspan=\"2\">\n" + "<form method=\"post\" action=\"{1}\" " + "enctype=\"multipart/form-data\">\n" + - "<input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{4}\" >" + "<table cellspacing=\"0\" cellpadding=\"3\">\n" + "<tr>\n" + " <td class=\"row-right\">\n" + @@ -1338,14 +1296,13 @@ public final class HTMLManagerServlet ex "<tr>\n" + " <td colspan=\"2\">\n" + "<form method=\"post\" action=\"{2}\">\n" + - "<input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{3}\" >" + "<table cellspacing=\"0\" cellpadding=\"3\">\n" + "<tr>\n" + " <td class=\"row-left\">\n" + - " <input type=\"submit\" value=\"{5}\">\n" + + " <input type=\"submit\" value=\"{4}\">\n" + " </td>\n" + " <td class=\"row-left\">\n" + - " <small>{4}</small>\n" + + " <small>{3}</small>\n" + " </td>\n" + "</tr>\n" + "</table>\n" + Modified: tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties?rev=957478&r1=957477&r2=957478&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties Thu Jun 24 09:57:02 2010 @@ -56,8 +56,6 @@ htmlManagerServlet.list=List Application htmlManagerServlet.manager=Manager htmlManagerServlet.messageLabel=Message: htmlManagerServlet.noManager=- -htmlManagerServlet.noNonce=FAIL: No nonce found in session. Command \"{0}\" was ignored -htmlManagerServlet.nonceMismatch=FAIL: Nonce mismatch. Command \"{0}\" was ignored. htmlManagerServlet.serverJVMVendor=JVM Vendor htmlManagerServlet.serverJVMVersion=JVM Version htmlManagerServlet.serverOSArch=OS Architecture Modified: tomcat/trunk/webapps/docs/config/filter.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/filter.xml?rev=957478&r1=957477&r2=957478&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/filter.xml (original) +++ tomcat/trunk/webapps/docs/config/filter.xml Thu Jun 24 09:57:02 2010 @@ -127,6 +127,14 @@ any security sensitive actions.</p> </attribute> + <attribute name="nonceCacheSize" required="false"> + <p>The number of previously issued nonces that will be cached on a LRU + basis to support parallel requests, limited use of the refresh and back + in the browser and similar behaviors that may result in the submission + of a previous nonce rather than the current one. If not set, the default + value of 5 will be used.</p> + </attribute> + </attributes> </subsection> Modified: tomcat/trunk/webapps/manager/403.jsp URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/manager/403.jsp?rev=957478&r1=957477&r2=957478&view=diff ============================================================================== --- tomcat/trunk/webapps/manager/403.jsp (original) +++ tomcat/trunk/webapps/manager/403.jsp Thu Jun 24 09:57:02 2010 @@ -33,7 +33,22 @@ <body> <h1>403 Access Denied</h1> <p> - You are not authorized to view this page. If you have not changed + You are not authorized to view this page. + </p> + <p> + If you have already configured the manager application to allow access and + you have used your browsers back button, used a saved bookmark or similar + then you may have triggered the cross-site request forgery (CSRF) protection + that has been enabled for the HTML interface of the Manager application. You + will need to reset this protection by returning to the + <a href="<%=request.getContextPath()%>/html">main manager page</a>. Once you + return to this page you will be able to continue using the manager + appliction's HTML interface normally. If you continue to see this access + denied message, check that you have the necessary permissions to access this + application. + </p> + <p> + If you have not changed any configuration files, please examine the file <tt>conf/tomcat-users.xml</tt> in your installation. That file must contain the credentials to let you use this webapp. Modified: tomcat/trunk/webapps/manager/WEB-INF/jsp/sessionDetail.jsp URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/manager/WEB-INF/jsp/sessionDetail.jsp?rev=957478&r1=957477&r2=957478&view=diff ============================================================================== --- tomcat/trunk/webapps/manager/WEB-INF/jsp/sessionDetail.jsp (original) +++ tomcat/trunk/webapps/manager/WEB-INF/jsp/sessionDetail.jsp Thu Jun 24 09:57:02 2010 @@ -31,18 +31,19 @@ Session currentSession = (Session)request.getAttribute("currentSession"); HttpSession currentHttpSession = currentSession.getSession(); String currentSessionId = currentSession.getId(); - String submitUrl = ((HttpServletRequest)pageContext.getRequest()).getRequestURL().toString(); + String submitUrl = response.encodeURL(((HttpServletRequest) + pageContext.getRequest()).getRequestURL().toString()); %> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/> - <meta http-equiv="pragma" content="no-cache"/><!-- HTTP 1.0 --> - <meta http-equiv="cache-control" content="no-cache,must-revalidate"/><!-- HTTP 1.1 --> - <meta http-equiv="expires" content="0"/><!-- 0 is an invalid value and should be treated as 'now' --> - <meta http-equiv="content-language" content="en"/> - <meta name="author" content="Cedrik LIME"/> - <meta name="copyright" content="copyright 2005-2010 the Apache Software Foundation"/> - <meta name="robots" content="noindex,nofollow,noarchive"/> - <title>Sessions Administration: details for <%= currentSessionId %></title> + <meta http-equiv="pragma" content="no-cache"/><!-- HTTP 1.0 --> + <meta http-equiv="cache-control" content="no-cache,must-revalidate"/><!-- HTTP 1.1 --> + <meta http-equiv="expires" content="0"/><!-- 0 is an invalid value and should be treated as 'now' --> + <meta http-equiv="content-language" content="en"/> + <meta name="author" content="Cedrik LIME"/> + <meta name="copyright" content="copyright 2005-2010 the Apache Software Foundation"/> + <meta name="robots" content="noindex,nofollow,noarchive"/> + <title>Sessions Administration: details for <%= currentSessionId %></title> </head> <body> <h1>Details for Session <%= JspHelper.escapeXml(currentSessionId) %></h1> @@ -86,7 +87,14 @@ </tr> </table> -<p style="text-align: center;"><button type="button" onclick="window.location.reload()">Refresh</button></p> +<form method="post" action="<%= submitUrl %>"> + <div> + <input type="hidden" name="path" value="<%= path %>" /> + <input type="hidden" name="sessionId" value="<%= currentSessionId %>" /> + <input type="hidden" name="action" value="sessionDetail" /> + <input type="submit" value="Refresh" /> + </div> +</form> <div class="error"><%= JspHelper.escapeXml(request.getAttribute("error")) %></div> <div class="message"><%= JspHelper.escapeXml(request.getAttribute("message")) %></div> @@ -95,52 +103,67 @@ <% int nAttributes = 0; Enumeration attributeNamesEnumeration = currentHttpSession.getAttributeNames(); while (attributeNamesEnumeration.hasMoreElements()) { - attributeNamesEnumeration.nextElement(); - ++nAttributes; + attributeNamesEnumeration.nextElement(); + ++nAttributes; } %> - <caption style="font-variant: small-caps;"><%= JspHelper.formatNumber(nAttributes) %> attributes</caption> - <thead> - <tr> - <th>Remove Attribute</th> - <th>Attribute name</th> - <th>Attribute value</th> - </tr> - </thead> - <%--tfoot> - <tr> - <td colspan="3" style="text-align: center;"> - TODO: set Max Inactive Interval on sessions - </td> - </tr> - </tfoot--%> - <tbody> + <caption style="font-variant: small-caps;"><%= JspHelper.formatNumber(nAttributes) %> attributes</caption> + <thead> + <tr> + <th>Remove Attribute</th> + <th>Attribute name</th> + <th>Attribute value</th> + </tr> + </thead> + <%--tfoot> + <tr> + <td colspan="3" style="text-align: center;"> + TODO: set Max Inactive Interval on sessions + </td> + </tr> + </tfoot--%> + <tbody> <% attributeNamesEnumeration = currentHttpSession.getAttributeNames(); while (attributeNamesEnumeration.hasMoreElements()) { - String attributeName = (String) attributeNamesEnumeration.nextElement(); + String attributeName = (String) attributeNamesEnumeration.nextElement(); %> - <tr> - <td align="center"><form action="<%= submitUrl %>"><div><input type="hidden" name="path" value="<%= path %>" /><input type="hidden" name="action" value="removeSessionAttribute" /><input type="hidden" name="sessionId" value="<%= currentSessionId %>" /><input type="hidden" name="attributeName" value="<%= attributeName %>" /><input type="submit" value="Remove" /></div></form></td> - <td><%= JspHelper.escapeXml(attributeName) %></td> - <td><% Object attributeValue = currentHttpSession.getAttribute(attributeName); %><span title="<%= attributeValue == null ? "" : attributeValue.getClass().toString() %>"><%= JspHelper.escapeXml(attributeValue) %></span></td> - </tr> + <tr> + <td align="center"> + <form method="post" action="<%= submitUrl %>"> + <div> + <input type="hidden" name="path" value="<%= path %>" /> + <input type="hidden" name="action" value="removeSessionAttribute" /> + <input type="hidden" name="sessionId" value="<%= currentSessionId %>" /> + <input type="hidden" name="attributeName" value="<%= attributeName %>" /> + <input type="submit" value="Remove" /> + </div> + </form> + </td> + <td><%= JspHelper.escapeXml(attributeName) %></td> + <td><% Object attributeValue = currentHttpSession.getAttribute(attributeName); %><span title="<%= attributeValue == null ? "" : attributeValue.getClass().toString() %>"><%= JspHelper.escapeXml(attributeValue) %></span></td> + </tr> <% } // end while %> - </tbody> + </tbody> </table> -<p style="text-align: center;"><button type="button" onclick="window.close()">Close window</button></p> +<form method="post" action="<%=submitUrl%>"> + <p style="text-align: center;"> + <input type="hidden" name="path" value="<%= path %>" /> + <input type="submit" value="Return to session list" /> + </p> +</form> <%--div style="display: none;"> <p> - <a href="http://validator.w3.org/check?uri=referer"><img - src="http://www.w3.org/Icons/valid-html401" - alt="Valid HTML 4.01!" height="31" width="88"></a> - <a href="http://validator.w3.org/check?uri=referer"><img - src="http://www.w3.org/Icons/valid-xhtml10" - alt="Valid XHTML 1.0!" height="31" width="88" /></a> - <a href="http://validator.w3.org/check?uri=referer"><img - src="http://www.w3.org/Icons/valid-xhtml11" - alt="Valid XHTML 1.1!" height="31" width="88" /></a> + <a href="http://validator.w3.org/check?uri=referer"><img + src="http://www.w3.org/Icons/valid-html401" + alt="Valid HTML 4.01!" height="31" width="88"></a> + <a href="http://validator.w3.org/check?uri=referer"><img + src="http://www.w3.org/Icons/valid-xhtml10" + alt="Valid XHTML 1.0!" height="31" width="88" /></a> + <a href="http://validator.w3.org/check?uri=referer"><img + src="http://www.w3.org/Icons/valid-xhtml11" + alt="Valid XHTML 1.1!" height="31" width="88" /></a> </p> </div--%> Modified: tomcat/trunk/webapps/manager/WEB-INF/jsp/sessionsList.jsp URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/manager/WEB-INF/jsp/sessionsList.jsp?rev=957478&r1=957477&r2=957478&view=diff ============================================================================== --- tomcat/trunk/webapps/manager/WEB-INF/jsp/sessionsList.jsp (original) +++ tomcat/trunk/webapps/manager/WEB-INF/jsp/sessionsList.jsp Thu Jun 24 09:57:02 2010 @@ -26,7 +26,8 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <% String path = (String) request.getAttribute("path"); - String submitUrl = ((HttpServletRequest)pageContext.getRequest()).getRequestURI() + "?path=" + path; + String submitUrl = response.encodeURL(((HttpServletRequest) + pageContext.getRequest()).getRequestURI() + "?path=" + path); Collection activeSessions = (Collection) request.getAttribute("activeSessions"); %> <head> @@ -99,7 +100,7 @@ %> <tr> <td> -<input type="checkbox" name="sessionIds" value="<%= currentSessionId %>" /><a href="<%= submitUrl %>&action=sessionDetail&sessionId=<%= currentSessionId %>" target="_blank"><%= JspHelper.escapeXml(currentSessionId) %></a> +<input type="checkbox" name="sessionIds" value="<%= currentSessionId %>" /><a href="<%= submitUrl %>&action=sessionDetail&sessionId=<%= currentSessionId %>"><%= JspHelper.escapeXml(currentSessionId) %></a> </td> <td style="text-align: center;"><%= JspHelper.guessDisplayLocaleFromSession(currentSession) %></td> <td style="text-align: center;"><%= JspHelper.guessDisplayUserFromSession(currentSession) %></td> @@ -118,7 +119,11 @@ </fieldset> </form> -<p style="text-align: center;"><button type="button" onclick="window.close()">Close window</button></p> +<form method="get" action="<%=request.getContextPath()%>/html"> + <p style="text-align: center;"> + <input type="submit" value="Return to main page" /> + </p> +</form> <%--div style="display: none;"> <p> Modified: tomcat/trunk/webapps/manager/WEB-INF/web.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/manager/WEB-INF/web.xml?rev=957478&r1=957477&r2=957478&view=diff ============================================================================== --- tomcat/trunk/webapps/manager/WEB-INF/web.xml (original) +++ tomcat/trunk/webapps/manager/WEB-INF/web.xml Thu Jun 24 09:57:02 2010 @@ -83,6 +83,21 @@ <url-pattern>/html/*</url-pattern> </servlet-mapping> + <filter> + <filter-name>CSRF</filter-name> + <filter-class>org.apache.catalina.filters.CsrfPreventionFilter</filter-class> + <init-param> + <param-name>entryPoints</param-name> + <param-value>/html,/html/,/html/list</param-value> + </init-param> + </filter> + + <filter-mapping> + <filter-name>CSRF</filter-name> + <servlet-name>HTMLManager</servlet-name> + <servlet-name>jsp</servlet-name> + </filter-mapping> + <!-- Define reference to the user database for looking up roles --> <resource-env-ref> <description> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org