You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Mark Thomas <ma...@apache.org> on 2010/11/22 20:11:43 UTC

[SECURITY] CVE-2010-4172: Apache Tomcat Manager application XSS vulnerability

-----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
%>&amp;action=sessionDetail&amp;sessionId=<%= currentSessionId %>"
target="_blank"><%= JspHelper.escapeXml(currentSessionId) %></a>
+<input type="checkbox" name="sessionIds" value="<%= currentSessionId
%>" /><a href="<%= submitUrl
%>&amp;action=sessionDetail&amp;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
%>&amp;action=sessionDetail&amp;sessionId=<%= currentSessionId
%>&amp;sessionType=<%= type %>"><%=
JspHelper.escapeXml(currentSessionId) %></a>
+                      <a href="<%= submitUrl
%>&amp;action=sessionDetail&amp;sessionId=<%= currentSessionId
%>&amp;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-----

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: [SECURITY] CVE-2010-4172: Apache Tomcat Manager application XSS vulnerability

Posted by Mark Thomas <ma...@apache.org>.
The processing of applying the digital signature to the original e-mail
made the patches hard to read. E-mail clients that can process digital
signatures should undo this formatting.

For those folks with an e-mail client that can't process OpenGPG signed
e-mail, the patches have been placed on the download mirrors as part of
the 6.0.29 and 7.0.4 distributions. To obtain the patches:

For Tomcat 6
- Open http://tomcat.apache.org/download-60.cgi
- Select 'Browse' from the Quick Navigation section
- Select the patches directory

For Tomcat 7
- Open http://tomcat.apache.org/download-70.cgi
- Select 'Browse' from the Quick Navigation section
- Select the patches directory

The Apache Tomcat Security Team

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: [SECURITY] CVE-2010-4172: Apache Tomcat Manager application XSS vulnerability

Posted by Mark Thomas <ma...@apache.org>.
The processing of applying the digital signature to the original e-mail
made the patches hard to read. E-mail clients that can process digital
signatures should undo this formatting.

For those folks with an e-mail client that can't process OpenGPG signed
e-mail, the patches have been placed on the download mirrors as part of
the 6.0.29 and 7.0.4 distributions. To obtain the patches:

For Tomcat 6
- Open http://tomcat.apache.org/download-60.cgi
- Select 'Browse' from the Quick Navigation section
- Select the patches directory

For Tomcat 7
- Open http://tomcat.apache.org/download-70.cgi
- Select 'Browse' from the Quick Navigation section
- Select the patches directory

The Apache Tomcat Security Team

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: [SECURITY] CVE-2010-4172: Apache Tomcat Manager application XSS vulnerability

Posted by Mark Thomas <ma...@apache.org>.
The processing of applying the digital signature to the original e-mail
made the patches hard to read. E-mail clients that can process digital
signatures should undo this formatting.

For those folks with an e-mail client that can't process OpenGPG signed
e-mail, the patches have been placed on the download mirrors as part of
the 6.0.29 and 7.0.4 distributions. To obtain the patches:

For Tomcat 6
- Open http://tomcat.apache.org/download-60.cgi
- Select 'Browse' from the Quick Navigation section
- Select the patches directory

For Tomcat 7
- Open http://tomcat.apache.org/download-70.cgi
- Select 'Browse' from the Quick Navigation section
- Select the patches directory

The Apache Tomcat Security Team