Protect yourself against future threats.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 =========================================================================== AUSCERT External Security Bulletin Redistribution ESB-2010.1064 Apache Tomcat Manager application XSS vulnerability 23 November 2010 =========================================================================== AusCERT Security Bulletin Summary --------------------------------- Product: Apache Tomcat 7.0.x Apache Tomcat 6.0.x Publisher: The Apache Software Foundation Operating System: UNIX variants (UNIX, Linux, OSX) Windows Impact/Access: Cross-site Scripting -- Remote with User Interaction Resolution: Patch/Upgrade CVE Names: CVE-2010-4172 - --------------------------BEGIN INCLUDED TEXT-------------------- - -----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----- - --------------------------END INCLUDED TEXT-------------------- You have received this e-mail bulletin as a result of your organisation's registration with AusCERT. The mailing list you are subscribed to is maintained within your organisation, so if you do not wish to continue receiving these bulletins you should contact your local IT manager. If you do not know who that is, please send an email to auscert@auscert.org.au and we will forward your request to the appropriate person. NOTE: Third Party Rights This security bulletin is provided as a service to AusCERT's members. As AusCERT did not write the document quoted above, AusCERT has had no control over its content. The decision to follow or act on information or advice contained in this security bulletin is the responsibility of each user or organisation, and should be considered in accordance with your organisation's site policies and procedures. AusCERT takes no responsibility for consequences which may arise from following or acting on information or advice contained in this security bulletin. NOTE: This is only the original release of the security bulletin. It may not be updated when updates to the original are made. If downloading at a later date, it is recommended that the bulletin is retrieved directly from the author's website to ensure that the information is still current. Contact information for the authors of the original document is included in the Security Bulletin above. If you have any questions or need further information, please contact them directly. Previous advisories and external security bulletins can be retrieved from: http://www.auscert.org.au/render.html?cid=1980 =========================================================================== Australian Computer Emergency Response Team The University of Queensland Brisbane Qld 4072 Internet Email: auscert@auscert.org.au Facsimile: (07) 3365 7031 Telephone: (07) 3365 4417 (International: +61 7 3365 4417) AusCERT personnel answer during Queensland business hours which are GMT+10:00 (AEST). On call after hours for member emergencies only. =========================================================================== -----BEGIN PGP SIGNATURE----- Comment: http://www.auscert.org.au/render.html?it=1967 iD8DBQFM6zKc/iFOrG6YcBERAjmWAJ9Pza29iHb2U3BYMqnQAun8QOlV8wCfQ8jp z8Xf3IJMEtM6G3Fd+ugk1m0= =cwzI -----END PGP SIGNATURE-----