-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 CVE-2010-4172: Apache Tomcat Manager application XSS vulnerability
Severity: Tomcat 7.0.x - Low, Tomcat 6.0.x - Moderate Vendor: The Apache Software Foundation Versions Affected: - - Tomcat 7.0.0 to 7.0.4 - Not affected in default configuration. - Affected if CSRF protection is disabled - Additional XSS issues if web applications are untrusted - - Tomcat 6.0.12 to 6.0.29 - Affected in default configuration - Additional XSS issues if web applications are untrusted - - Tomcat 5.5.x - Not affected Description: The session list screen (provided by sessionList.jsp) in affected versions uses the orderBy and sort request parameters without applying filtering and therefore is vulnerable to a cross-site scripting attack. Users should be aware that Tomcat 6 does not use httpOnly for session cookies by default so this vulnerability could expose session cookies from the manager application to an attacker. A review of the Manager application by the Apache Tomcat security team identified additional XSS vulnerabilities if the web applications deployed were not trusted. Example: GET /manager/html/sessions?path=/&sort="><script>alert('xss')</script>order=ASC&action=injectSessions&refresh=Refresh+Sessions+list Mitigation: Users of affected versions should apply one of the following mitigations - - Tomcat 7.0.0 to 7.0.4 - Remove the Manager application - Remove the sessionList.jsp and sessionDetail.jsp files - Ensure the CSRF protection is enabled - Apply the patch 7.0.4 patch (see below) - Update to 7.0.5 when released - - Tomcat 6.0.12 to 6.0.29 - Remove the Manager application - Remove the sessionList.jsp and sessionDetail.jsp files - Apply the patch for 6.0.29 (see below) - Update to 6.0.30 when released No release date has been set for the next Tomcat 7.0.x and Tomcat 6.0.x releases. Credit: The original issue was discovered by Adam Muntner of Gotham Digital Science. Additional issues were identified by the Tomcat security team as a result of reviewing the original issue. References: http://tomcat.apache.org/security.html http://tomcat.apache.org/security-7.html http://tomcat.apache.org/security-6.html Note: The patches The Apache Tomcat Security Team **************** Patch for 6.0.29 **************** Index: webapps/manager/WEB-INF/jsp/sessionDetail.jsp =================================================================== - --- webapps/manager/WEB-INF/jsp/sessionDetail.jsp (revision 1037769) +++ webapps/manager/WEB-INF/jsp/sessionDetail.jsp (working copy) @@ -30,8 +30,10 @@ <% String path = (String) request.getAttribute("path"); Session currentSession = (Session)request.getAttribute("currentSession"); HttpSession currentHttpSession = currentSession.getSession(); - - String currentSessionId = currentSession.getId(); - - String submitUrl = ((HttpServletRequest)pageContext.getRequest()).getRequestURL().toString(); + String currentSessionId = JspHelper.escapeXml(currentSession.getId()); + String submitUrl = JspHelper.escapeXml( + ((HttpServletRequest) pageContext.getRequest()).getRequestURI() + + "?path=" + path); %> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/> @@ -45,7 +47,7 @@ <title>Sessions Administration: details for <%= currentSessionId %></title> </head> <body> - -<h1>Details for Session <%= JspHelper.escapeXml(currentSessionId) %></h1> +<h1>Details for Session <%= currentSessionId %></h1> <table style="text-align: left;" border="0"> <tr> @@ -54,7 +56,7 @@ </tr> <tr> <th>Guessed Locale</th> - - <td><%= JspHelper.guessDisplayLocaleFromSession(currentSession) %></td> + <td><%= JspHelper.escapeXml(JspHelper.guessDisplayLocaleFromSession(currentSession)) %></td> </tr> <tr> <th>Guessed User</th> @@ -120,7 +122,7 @@ 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 align="center"><form action="<%= submitUrl %>"><div><input type="hidden" name="action" value="removeSessionAttribute" /><input type="hidden" name="sessionId" value="<%= currentSessionId %>" /><input type="hidden" name="attributeName" value="<%= JspHelper.escapeXml(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> Index: webapps/manager/WEB-INF/jsp/sessionsList.jsp =================================================================== - --- webapps/manager/WEB-INF/jsp/sessionsList.jsp (revision 1037769) +++ webapps/manager/WEB-INF/jsp/sessionsList.jsp (working copy) @@ -26,7 +26,9 @@ <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 = JspHelper.escapeXml( + ((HttpServletRequest) pageContext.getRequest()).getRequestURI() + + "?path=" + path); Collection activeSessions = (Collection) request.getAttribute("activeSessions"); %> <head> @@ -38,10 +40,10 @@ <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 for <%= path %></title> + <title>Sessions Administration for <%= JspHelper.escapeXml(path) %></title> </head> <body> - -<h1>Sessions Administration for <%= path %></h1> +<h1>Sessions Administration for <%= JspHelper.escapeXml(path) %></h1> <p>Tips:</p> <ul> @@ -55,13 +57,13 @@ <form action="<%= submitUrl %>" method="post" id="sessionsForm"> <fieldset><legend>Active HttpSessions informations</legend> <input type="hidden" name="action" id="sessionsFormAction" value="injectSessions"/> - - <input type="hidden" name="sort" id="sessionsFormSort" value="<%= (String) request.getAttribute("sort") %>"/> + <input type="hidden" name="sort" id="sessionsFormSort" value="<%= JspHelper.escapeXml(request.getAttribute("sort")) %>"/> <% String order = (String) request.getAttribute("order"); if (order == null || "".equals(order)) { order = "ASC"; } %> - - <input type="hidden" name="order" id="sessionsFormSortOrder" value="<%= order %>"/> + <input type="hidden" name="order" id="sessionsFormSortOrder" value="<%= JspHelper.escapeXml(order) %>"/> <input type="submit" name="refresh" id="refreshButton" value="Refresh Sessions list" onclick="document.getElementById('sessionsFormAction').value='refreshSessions'; return true;"/> <%= JspHelper.formatNumber(activeSessions.size()) %> active Sessions<br/> <table border="1" cellpadding="2" cellspacing="2" width="100%"> @@ -95,13 +97,13 @@ <% Iterator iter = activeSessions.iterator(); while (iter.hasNext()) { Session currentSession = (Session) iter.next(); - - String currentSessionId = currentSession.getId(); + String currentSessionId = JspHelper.escapeXml(currentSession.getId()); %> <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 %>" target="_blank"><%= currentSessionId %></a> </td> - - <td style="text-align: center;"><%= JspHelper.guessDisplayLocaleFromSession(currentSession) %></td> + <td style="text-align: center;"><%= JspHelper.escapeXml(JspHelper.guessDisplayLocaleFromSession(currentSession)) %></td> <td style="text-align: center;"><%= JspHelper.guessDisplayUserFromSession(currentSession) %></td> <td style="text-align: center;"><%= JspHelper.getDisplayCreationTimeForSession(currentSession) %></td> <td style="text-align: center;"><%= JspHelper.getDisplayLastAccessedTimeForSession(currentSession) %></td> *************** Patch for 7.0.4 *************** Index: webapps/manager/WEB-INF/jsp/sessionDetail.jsp =================================================================== - --- webapps/manager/WEB-INF/jsp/sessionDetail.jsp (revision 1037768) +++ webapps/manager/WEB-INF/jsp/sessionDetail.jsp (working copy) @@ -30,9 +30,10 @@ <% String path = (String) request.getAttribute("path"); Session currentSession = (Session)request.getAttribute("currentSession"); HttpSession currentHttpSession = currentSession.getSession(); - - String currentSessionId = currentSession.getId(); - - String submitUrl = response.encodeURL(((HttpServletRequest) - - pageContext.getRequest()).getRequestURL().toString()); + String currentSessionId = JspHelper.escapeXml(currentSession.getId()); + String submitUrl = JspHelper.escapeXml(response.encodeURL( + ((HttpServletRequest) pageContext.getRequest()).getRequestURI() + + "?path=" + path)); %> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/> @@ -46,7 +47,7 @@ <title>Sessions Administration: details for <%= currentSessionId %></title> </head> <body> - -<h1>Details for Session <%= JspHelper.escapeXml(currentSessionId) %></h1> +<h1>Details for Session <%= currentSessionId %></h1> <table style="text-align: left;" border="0"> <tr> @@ -55,7 +56,7 @@ </tr> <tr> <th>Guessed Locale</th> - - <td><%= JspHelper.guessDisplayLocaleFromSession(currentSession) %></td> + <td><%= JspHelper.escapeXml(JspHelper.guessDisplayLocaleFromSession(currentSession)) %></td> </tr> <tr> <th>Guessed User</th> @@ -89,7 +90,6 @@ <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" /> @@ -131,10 +131,9 @@ <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="hidden" name="attributeName" value="<%= JspHelper.escapeXml(attributeName) %>" /> <% if ("Primary".equals(request.getAttribute("sessionType"))) { %> @@ -156,7 +155,6 @@ <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> Index: webapps/manager/WEB-INF/jsp/sessionsList.jsp =================================================================== - --- webapps/manager/WEB-INF/jsp/sessionsList.jsp (revision 1037768) +++ webapps/manager/WEB-INF/jsp/sessionsList.jsp (working copy) @@ -28,8 +28,9 @@ <%...@page import="org.apache.catalina.manager.DummyProxySession"%><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <% String path = (String) request.getAttribute("path"); - - String submitUrl = response.encodeURL(((HttpServletRequest) - - pageContext.getRequest()).getRequestURI() + "?path=" + path); + String submitUrl = JspHelper.escapeXml(response.encodeURL( + ((HttpServletRequest) pageContext.getRequest()).getRequestURI() + + "?path=" + path)); Collection activeSessions = (Collection) request.getAttribute("activeSessions"); %> <head> @@ -41,10 +42,10 @@ <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 for <%= path %></title> + <title>Sessions Administration for <%= JspHelper.escapeXml(path) %></title> </head> <body> - -<h1>Sessions Administration for <%= path %></h1> +<h1>Sessions Administration for <%= JspHelper.escapeXml(path) %></h1> <p>Tips:</p> <ul> @@ -58,13 +59,13 @@ <form action="<%= submitUrl %>" method="post" id="sessionsForm"> <fieldset><legend>Active HttpSessions informations</legend> <input type="hidden" name="action" id="sessionsFormAction" value="injectSessions"/> - - <input type="hidden" name="sort" id="sessionsFormSort" value="<%= (String) request.getAttribute("sort") %>"/> + <input type="hidden" name="sort" id="sessionsFormSort" value="<%= JspHelper.escapeXml(request.getAttribute("sort")) %>"/> <% String order = (String) request.getAttribute("order"); if (order == null || "".equals(order)) { order = "ASC"; } %> - - <input type="hidden" name="order" id="sessionsFormSortOrder" value="<%= order %>"/> + <input type="hidden" name="order" id="sessionsFormSortOrder" value="<%= JspHelper.escapeXml(order) %>"/> <input type="submit" name="refresh" id="refreshButton" value="Refresh Sessions list" onclick="document.getElementById('sessionsFormAction').value='refreshSessions'; return true;"/> <%= JspHelper.formatNumber(activeSessions.size()) %> active Sessions<br/> <table border="1" cellpadding="2" cellspacing="2" width="100%"> @@ -100,7 +101,7 @@ <% Iterator iter = activeSessions.iterator(); while (iter.hasNext()) { Session currentSession = (Session) iter.next(); - - String currentSessionId = currentSession.getId(); + String currentSessionId = JspHelper.escapeXml(currentSession.getId()); String type; if (currentSession instanceof DeltaSession) { if (((DeltaSession) currentSession).isPrimarySession()) { @@ -121,13 +122,13 @@ out.print(currentSessionId); } else { %> - - <a href="<%= submitUrl %>&action=sessionDetail&sessionId=<%= currentSessionId %>&sessionType=<%= type %>"><%= JspHelper.escapeXml(currentSessionId) %></a> + <a href="<%= submitUrl %>&action=sessionDetail&sessionId=<%= currentSessionId %>&sessionType=<%= type %>"><%= currentSessionId %></a> <% } %> </td> <td style="text-align: center;"><%= type %></td> - - <td style="text-align: center;"><%= JspHelper.guessDisplayLocaleFromSession(currentSession) %></td> + <td style="text-align: center;"><%= JspHelper.escapeXml(JspHelper.guessDisplayLocaleFromSession(currentSession)) %></td> <td style="text-align: center;"><%= JspHelper.guessDisplayUserFromSession(currentSession) %></td> <td style="text-align: center;"><%= JspHelper.getDisplayCreationTimeForSession(currentSession) %></td> <td style="text-align: center;"><%= JspHelper.getDisplayLastAccessedTimeForSession(currentSession) %></td> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQIcBAEBAgAGBQJM6sBuAAoJEBDAHFovYFnnrHEQAPA2QmgMopWAzEynFt0htLUS Dx0A8gl4grLLIjDcwCM+jzc44dn0zzSTuXZkhAbCE+gnLpQSCMf1iQmX3hwOKCHx MgHpWIhpon6FB1+AE3HtqQ2MzH/IUeA0ji2F/nWKors4zdkdpNNZG3O4tNzsd108 IXrDaoJheD0ek9N51PYAuN1ZEhMWnkTYPvpGjCcSn5sj2LYqEGpdrifLBx5QbwZu eOVJHufomeU6lanogTtSaXUhDmfm0NM72OCxm597R9L10Xll2D2AK0MvTZjWf5Mr xZiotdlFc6E5PPNtdUOO34HW/ClYrTjWQB1RoY8yUnRjRx8a8tZ+rrX9TCfPuy7x Os8nOEAjWtUYZmP4I+o0c8tcurpF9gP6rITOL4JZlZPB++ZtzILU4NGzoxsQ5WtZ U1eIgnH1GcboOAu0TKfxESrDFutruN9PvgIaQPdBftENShk20CNBXfaWatkE0nnv YZS9R5dviKa/u7cNZEusGQirc65bdDuG2u97bZkqoYyywwpeBC7QKEiPfqnfa9Ju DkucGnejMDbWa5kgvDQH/i0vnyy2lyknGo/vuZMsgVWffgKQoLG0TLk4hg4Evafv nWeeepnIdDTTc2KuiqO1F/KSGB7VmR8E2ySGj62g75bJOnSzVMpSpwfF/F7FYMsi NAKAGVImnKte7ogGqU94 =gjUw -----END PGP SIGNATURE-----