Author: markt Date: Fri Jun 25 07:47:31 2010 New Revision: 957828 URL: http://svn.apache.org/viewvc?rev=957828&view=rev Log: Switch the Host Manager app to the generic CSRF protection Don't allow starting of hosts that are started Don't allow stopping of hosts that are stopped
Modified: tomcat/trunk/java/org/apache/catalina/manager/host/HTMLHostManagerServlet.java tomcat/trunk/java/org/apache/catalina/manager/host/HostManagerServlet.java tomcat/trunk/java/org/apache/catalina/manager/host/LocalStrings.properties tomcat/trunk/webapps/host-manager/403.jsp tomcat/trunk/webapps/host-manager/WEB-INF/web.xml Modified: tomcat/trunk/java/org/apache/catalina/manager/host/HTMLHostManagerServlet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/host/HTMLHostManagerServlet.java?rev=957828&r1=957827&r2=957828&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/manager/host/HTMLHostManagerServlet.java (original) +++ tomcat/trunk/java/org/apache/catalina/manager/host/HTMLHostManagerServlet.java Fri Jun 25 07:47:31 2010 @@ -25,13 +25,11 @@ import java.net.URLEncoder; import java.text.MessageFormat; import java.util.Iterator; import java.util.Map; -import java.util.Random; import java.util.TreeMap; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import org.apache.catalina.Container; import org.apache.catalina.Host; @@ -65,12 +63,6 @@ public final class HTMLHostManagerServle private static final long serialVersionUID = 1L; - protected static final String NONCE_SESSION = - "org.apache.catalina.manager.host.NONCE"; - protected static final String NONCE_REQUEST = "nonce"; - - private final Random randomSource = new Random(); - // --------------------------------------------------------- Public Methods /** @@ -129,31 +121,12 @@ public final class HTMLHostManagerServle String command = request.getPathInfo(); String name = request.getParameter("name"); - 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("htmlHostManagerServlet.noNonce", command); - // Reset the command - command = null; - } else { - if (!sessionNonce.equals(requestNonce)) { - // Nonce mis-match. - message = - sm.getString("htmlHostManagerServlet.nonceMismatch", command); - // Reset the command - command = null; - } - } - // Process the requested command if (command == null) { // No command == list @@ -175,37 +148,6 @@ public final class HTMLHostManagerServle /** - * Generate a once time token (nonce) for authenticating subsequent - * requests. This will also add the token to the session. The nonce - * generation is a simplified version of ManagerBase.generateSessionId(). - * - */ - protected String generateNonce() { - byte random[] = new byte[16]; - - // Render the result as a String of hexadecimal digits - StringBuilder buffer = new StringBuilder(); - - randomSource.nextBytes(random); - - for (int j = 0; j < random.length; j++) { - byte b1 = (byte) ((random[j] & 0xf0) >> 4); - byte b2 = (byte) (random[j] & 0x0f); - if (b1 < 10) - buffer.append((char) ('0' + b1)); - else - buffer.append((char) ('A' + (b1 - 10))); - if (b2 < 10) - buffer.append((char) ('0' + b2)); - else - buffer.append((char) ('A' + (b2 - 10))); - } - - return buffer.toString(); - } - - - /** * Add a host using the specified parameters. * * @param name host name @@ -286,9 +228,6 @@ public final class HTMLHostManagerServle log(sm.getString("hostManagerServlet.list", engine.getName())); } - String newNonce = generateNonce(); - request.getSession().setAttribute(NONCE_SESSION, newNonce); - PrintWriter writer = response.getWriter(); // HTML Header Section @@ -383,23 +322,25 @@ public final class HTMLHostManagerServle writer.print (MessageFormat.format(HOSTS_ROW_DETAILS_SECTION, args)); - args = new Object[7]; - args[0] = response.encodeURL - (request.getContextPath() + - "/html/start?name=" + - URLEncoder.encode(hostName, "UTF-8")); - args[1] = hostsStart; - args[2] = response.encodeURL + args = new Object[4]; + if (host.getState().isAvailable()) { + args[0] = response.encodeURL (request.getContextPath() + "/html/stop?name=" + URLEncoder.encode(hostName, "UTF-8")); - args[3] = hostsStop; - args[4] = response.encodeURL + args[1] = hostsStop; + } else { + args[0] = response.encodeURL + (request.getContextPath() + + "/html/start?name=" + + URLEncoder.encode(hostName, "UTF-8")); + args[1] = hostsStart; + } + args[2] = response.encodeURL (request.getContextPath() + "/html/remove?name=" + URLEncoder.encode(hostName, "UTF-8")); - args[5] = hostsRemove; - args[6] = newNonce; + args[3] = hostsRemove; if (host == this.installedHost) { writer.print(MessageFormat.format( MANAGER_HOST_ROW_BUTTON_SECTION, args)); @@ -407,19 +348,17 @@ public final class HTMLHostManagerServle writer.print(MessageFormat.format( HOSTS_ROW_BUTTON_SECTION, args)); } - } } // Add Section - args = new Object[7]; + args = new Object[6]; args[0] = sm.getString("htmlHostManagerServlet.addTitle"); args[1] = sm.getString("htmlHostManagerServlet.addHost"); args[2] = response.encodeURL(request.getContextPath() + "/html/add"); args[3] = sm.getString("htmlHostManagerServlet.addName"); args[4] = sm.getString("htmlHostManagerServlet.addAliases"); args[5] = sm.getString("htmlHostManagerServlet.addAppBase"); - args[6] = newNonce; writer.print(MessageFormat.format(ADD_SECTION_START, args)); args = new Object[3]; @@ -514,9 +453,7 @@ public final class HTMLHostManagerServle private static final String MANAGER_HOST_ROW_BUTTON_SECTION = " <td class=\"row-left\">\n" + " <small>\n" + - " {1} \n" + - " {3} \n" + - " {5} \n" + + sm.getString("htmlHostManagerServlet.hostThis") + " </small>\n" + " </td>\n" + "</tr>\n"; @@ -524,17 +461,11 @@ public final class HTMLHostManagerServle private static final String HOSTS_ROW_BUTTON_SECTION = " <td class=\"row-left\" NOWRAP>\n" + " <form class=\"inline\" method=\"POST\" action=\"{0}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{6}\"" + " <small><input type=\"submit\" value=\"{1}\"></small>" + " </form>\n" + " <form class=\"inline\" method=\"POST\" action=\"{2}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{6}\"" + " <small><input type=\"submit\" value=\"{3}\"></small>" + " </form>\n" + - " <form class=\"inline\" method=\"POST\" action=\"{4}\">" + - " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{6}\"" + - " <small><input type=\"submit\" value=\"{5}\"></small>" + - " </form>\n" + " </td>\n" + "</tr>\n"; @@ -551,7 +482,6 @@ public final class HTMLHostManagerServle "<tr>\n" + " <td colspan=\"2\">\n" + "<form method=\"post\" action=\"{2}\">\n" + - "<input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{6}\"\n" + "<table cellspacing=\"0\" cellpadding=\"3\">\n" + "<tr>\n" + " <td class=\"row-right\">\n" + Modified: tomcat/trunk/java/org/apache/catalina/manager/host/HostManagerServlet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/host/HostManagerServlet.java?rev=957828&r1=957827&r2=957828&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/manager/host/HostManagerServlet.java (original) +++ tomcat/trunk/java/org/apache/catalina/manager/host/HostManagerServlet.java Fri Jun 25 07:47:31 2010 @@ -583,6 +583,13 @@ public class HostManagerServlet return; } + // Don't start host of already started + if (host.getState().isAvailable()) { + writer.println + (sm.getString("hostManagerServlet.alreadyStarted", name)); + return; + } + // Start host try { host.start(); @@ -635,7 +642,14 @@ public class HostManagerServlet return; } - // Start host + // Don't stop host of already stopped + if (!host.getState().isAvailable()) { + writer.println + (sm.getString("hostManagerServlet.alreadyStopped", name)); + return; + } + + // Stop host try { host.stop(); writer.println Modified: tomcat/trunk/java/org/apache/catalina/manager/host/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/host/LocalStrings.properties?rev=957828&r1=957827&r2=957828&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/manager/host/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/manager/host/LocalStrings.properties Fri Jun 25 07:47:31 2010 @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +hostManagerServlet.alreadyStarted=FAIL - Host [{0}] is already started +hostManagerServlet.alreadyStopped=FAIL - Host [{0}] is already stopped hostManagerServlet.appBaseCreateFail=FAIL - Failed to create appBase [{0}] for host [{1}] hostManagerServlet.configBaseCreateFail=FAIL - Failed to identify configBase for host [{0}] hostManagerServlet.noCommand=FAIL - No command was specified @@ -57,6 +59,7 @@ htmlHostManagerServlet.hostTasks=Command htmlHostManagerServlet.hostsStart=Start htmlHostManagerServlet.hostsStop=Stop htmlHostManagerServlet.hostsRemove=Remove +htmlHostManagerServlet.hostThis=Host Manager installed - commands disabled htmlHostManagerServlet.addTitle=Add Virtual Host htmlHostManagerServlet.addHost=Host htmlHostManagerServlet.addName=Name: @@ -77,8 +80,6 @@ htmlHostManagerServlet.serverJVMVendor=J htmlHostManagerServlet.serverOSName=OS Name htmlHostManagerServlet.serverOSVersion=OS Version htmlHostManagerServlet.serverOSArch=OS Architecture -htmlHostManagerServlet.noNonce=FAIL: No nonce found in session. Command \"{0}\" was ignored -htmlHostManagerServlet.nonceMismatch=FAIL: Nonce mismatch. Command \"{0}\" was ignored. statusServlet.title=Server Status statusServlet.complete=Complete Server Status Modified: tomcat/trunk/webapps/host-manager/403.jsp URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/host-manager/403.jsp?rev=957828&r1=957827&r2=957828&view=diff ============================================================================== --- tomcat/trunk/webapps/host-manager/403.jsp (original) +++ tomcat/trunk/webapps/host-manager/403.jsp Fri Jun 25 07:47:31 2010 @@ -33,7 +33,21 @@ <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 Host Manager application to allow access + and you have used your browsers back button, used a saved book-mark or + similar then you may have triggered the cross-site request forgery (CSRF) + protection that has been enabled for the HTML interface of the Host Manager + application. You will need to reset this protection by returning to the + <a href="<%=request.getContextPath()%>/html">main Host Manager page</a>. + Once you return to this page, you will be able to continue using the Host + 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/host-manager/WEB-INF/web.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/host-manager/WEB-INF/web.xml?rev=957828&r1=957827&r2=957828&view=diff ============================================================================== --- tomcat/trunk/webapps/host-manager/WEB-INF/web.xml (original) +++ tomcat/trunk/webapps/host-manager/WEB-INF/web.xml Fri Jun 25 07:47:31 2010 @@ -46,6 +46,20 @@ </init-param> </servlet> + <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>HTMLHostManager</servlet-name> + </filter-mapping> + <!-- Define the Manager Servlet Mapping --> <servlet-mapping> <servlet-name>HostManager</servlet-name> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org