CVE-2021-25932: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: In OpenNMS Horizon, versions opennms-1-0-stable through opennms-27.1.0-1; OpenNMS Meridian, versions meridian-foundation-2015.1.0-1 through meridian-foundation-2019.1.18-1; meridian-foundation-2020.1.0-1 through meridian-foundation-2020.1.6-1 are vulnerable to Stored Cross-Site Scripting, since the function `validateFormInput()` performs improper validation checks on the input sent to the `userID` parameter. Due to this flaw an attacker could inject an arbitrary script which will be stored in the database.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 5.4
Published: 2021-06-01T12:15Z
Repository: https://github.com/OpenNMS/opennms
Language: Other
Files changed: opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/groupDetail.jsp, opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/list.jsp, opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/modifyGroup.jsp, opennms-webapp/src/main/webapp/WEB-INF/jsp/alarm/detail.jsp, opennms-webapp/src/main/webapp/WEB-INF/jsp/event/detail.jsp, opennms-webapp/src/main/webapp/WEB-INF/jsp/outage/detail.jsp, opennms-webapp/src/main/webapp/admin/userGroupView/users/list.jsp, opennms-webapp/src/main/webapp/admin/userGroupView/users/modifyUser.jsp, opennms-webapp/src/main/webapp/admin/userGroupView/users/userDetail.jsp, opennms-webapp/src/main/webapp/notification/detail.jsp
Commit date: 2021-03-05 08:26:14 +0100
Commit message: NMS-13125: Escape userId & groupId


Diff: diff --git a/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/groupDetail.jsp b/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/groupDetail.jsp
index 623c9bc5c76..de4c0c8efe8 100644
--- a/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/groupDetail.jsp
+++ b/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/groupDetail.jsp
@@ -38,10 +38,11 @@
 		org.opennms.netmgt.config.users.DutySchedule
 	"
 %>
 
 <%@page import="org.opennms.web.group.WebGroup"%>
+<%@ page import="org.opennms.core.utils.WebSecurityUtils" %>
 
 <%
     WebGroup group = (WebGroup)request.getAttribute("group");
 %>
 
@@ -58,17 +59,17 @@
 
 <div class="row">
   <div class="col-md-6">
     <div class="card">
       <div class="card-header">
-        <span>Details for Group: <%=group.getName()%></span>
+        <span>Details for Group: <%=WebSecurityUtils.sanitizeString(group.getName())%></span>
       </div>
       <table class="table table-sm">
         <tr>
           <th>Comments:</th>
           <td width="75%">
-            <%=group.getComments()%>
+            <%=WebSecurityUtils.sanitizeString(group.getComments())%>
           </td>
         </tr>
         <tr>
           <th>Assigned Users:</th>
           <td width="75%">
@@ -77,11 +78,11 @@
             { %>
               No users belong to this group.
             <% } else { %>
               <ul class="list-unstyled">
               <% for (String user : users) { %>
-               <li> <%=user%> </li>
+               <li> <%=WebSecurityUtils.sanitizeString(user)%> </li>
               <% } %>
               </ul>
             <% } %>
           </td>
         </tr>
diff --git a/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/list.jsp b/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/list.jsp
index 4d9734b5268..03c093acaa8 100644
--- a/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/list.jsp
+++ b/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/list.jsp
@@ -28,10 +28,11 @@
  *******************************************************************************/
 
 --%>
 
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
 
 <jsp:include page="/includes/bootstrap.jsp" flush="false" >
   <jsp:param name="title" value="Group Configuration" />
   <jsp:param name="headTitle" value="List" />
   <jsp:param name="headTitle" value="Groups" />
@@ -114,41 +115,41 @@
           <th>Rename</th>
           <th>Group Name</th>
           <th>Comments</th>
         </tr>
          <c:forEach var="group" varStatus="groupStatus" items="${groups}">
-         <tr class="divider ${groupStatus.index % 2 == 0 ?  'even' : 'odd'}" id="group-${group.name}">
+         <tr class="divider ${groupStatus.index % 2 == 0 ?  'even' : 'odd'}" id="group-${fn:escapeXml(group.name)}">
           <td width="5%" class="text-center">
             <c:choose>
-              <c:when test='${group.name != "Admin"}'>
-                <a id="${group.name}.doDelete" href="javascript:deleteGroup('${group.name}')" onclick="return confirm('Are you sure you want to delete the group ${group.name}?')"><i class="fa fa-trash-o fa-2x"></i></a>              
+              <c:when test='${fn:escapeXml(group.name) != "Admin"}'>
+                <a id="${group.name}.doDelete" href="javascript:deleteGroup('${fn:escapeXml(group.name)}')" onclick="return confirm('Are you sure you want to delete the group ${fn:escapeXml(group.name)}?')"><i class="fa fa-trash-o fa-2x"></i></a>
               </c:when>
               <c:otherwise>
-                <i class="fa fa-trash-o fa-2x" onclick="alert('Sorry, the ${group.name} group cannot be deleted.')"></i>
+                <i class="fa fa-trash-o fa-2x" onclick="alert('Sorry, the ${fn:escapeXml(group.name)} group cannot be deleted.')"></i>
               </c:otherwise>
             </c:choose>
           </td>
           <td width="5%" class="text-center">
-            <a id="${group.name}.doModify" href="javascript:modifyGroup('${group.name}')"><i class="fa fa-edit fa-2x"></i></a>
+            <a id="${fn:escapeXml(group.name)}.doModify" href="javascript:modifyGroup('${fn:escapeXml(group.name)}')"><i class="fa fa-edit fa-2x"></i></a>
           </td>
           <td width="5%" class="text-center">
             <c:choose>
               <c:when test='${group.name != "Admin"}'>
-                <button id="${group.name}.doRename" type="button" class="btn btn-secondary" name="rename" onclick="renameGroup('${group.name}')">Rename</button>
+                <button id="${fn:escapeXml(group.name)}.doRename" type="button" class="btn btn-secondary" name="rename" onclick="renameGroup('${fn:escapeXml(group.name)}')">Rename</button>
               </c:when>
               <c:otherwise>
-                <button id="${group.name}.doRename" type="button" class="btn btn-secondary" name="rename" onclick="alert('Sorry, the Admin group cannot be renamed.')">Rename</button>
+                <button id="${fn:escapeXml(group.name)}.doRename" type="button" class="btn btn-secondary" name="rename" onclick="alert('Sorry, the Admin group cannot be renamed.')">Rename</button>
               </c:otherwise>
             </c:choose>
           </td>
           <td>
-            <a href="javascript:detailGroup('${group.name}')">${group.name}</a>
+            <a href="javascript:detailGroup('${fn:escapeXml(group.name)}')">${fn:escapeXml(group.name)}</a>
           </td>
             <td>
               <c:choose>
                 <c:when test="${group.comments.isPresent()}">
-                  ${group.comments.get()}
+                  ${fn:escapeXml(group.comments.get())}
                 </c:when>
                 
                 <c:otherwise>
                   No Comments
                 </c:otherwise>
diff --git a/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/modifyGroup.jsp b/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/modifyGroup.jsp
index c70e61e3487..b4fc9a574cd 100644
--- a/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/modifyGroup.jsp
+++ b/opennms-webapp/src/main/webapp/WEB-INF/jsp/admin/userGroupView/groups/modifyGroup.jsp
@@ -37,10 +37,11 @@
 		java.text.*,
 		org.opennms.netmgt.config.users.*
 	"
 %>
 <%@page import="org.opennms.web.group.WebGroup"%>
+<%@ page import="org.opennms.core.utils.WebSecurityUtils" %>
 
 <%
   	WebGroup group = (WebGroup)session.getAttribute("group.modifyGroup.jsp");
     if (group == null) {
         throw new ServletException("Could not get session attribute group");
@@ -461,11 +462,11 @@
 
 <%!
     private String createSelectList(String name, String[] categories) {
         StringBuffer buffer = new StringBuffer("<select class=\"form-control custom-select\" multiple=\"multiple\" name=\""+name+"\" size=\"10\">");
         for(String category : categories){
-            buffer.append("<option>" + category + "</option>");
+            buffer.append("<option>" + WebSecurityUtils.sanitizeString(category) + "</option>");
         }
         buffer.append("</select>");
         
         return buffer.toString();
     }
diff --git a/opennms-webapp/src/main/webapp/WEB-INF/jsp/alarm/detail.jsp b/opennms-webapp/src/main/webapp/WEB-INF/jsp/alarm/detail.jsp
index cb6d70aa2cf..523863ed912 100644
--- a/opennms-webapp/src/main/webapp/WEB-INF/jsp/alarm/detail.jsp
+++ b/opennms-webapp/src/main/webapp/WEB-INF/jsp/alarm/detail.jsp
@@ -447,11 +447,11 @@
         <th>Acknowledged&nbsp;Type</th>
         <th>Time&nbsp;Acknowledged</th>
     </tr>
     <% for (OnmsAcknowledgment ack : acks) {%>
     <tr class="severity-<%=alarm.getSeverity().getLabel().toLowerCase()%>">
-        <td><%=ack.getAckUser()%></td>
+        <td><%=WebSecurityUtils.sanitizeString(ack.getAckUser())%></td>
         <td><%=ack.getAckAction()%></td>
         <td><onms:datetime date="<%=ack.getAckTime()%>" /></td>
     </tr>
     <% }%>
 </table>
diff --git a/opennms-webapp/src/main/webapp/WEB-INF/jsp/event/detail.jsp b/opennms-webapp/src/main/webapp/WEB-INF/jsp/event/detail.jsp
index 79caff231d4..726ad12e22e 100644
--- a/opennms-webapp/src/main/webapp/WEB-INF/jsp/event/detail.jsp
+++ b/opennms-webapp/src/main/webapp/WEB-INF/jsp/event/detail.jsp
@@ -105,11 +105,11 @@
           <th class="col-1">Severity</th>
           <td class="col-3 bright"><%= event.getSeverity().getLabel() %></td>
           <th class="col-1">Node</th>
           <td ${acknowledgeEvent ? '' : 'colspan="3"'} class="${acknowledgeEvent ? 'col-3' : 'col-7'}">
             <% if( event.getNodeId() > 0 ) { %>
-              <a href="element/node.jsp?node=<%=event.getNodeId()%>"><%=event.getNodeLabel()%></a>
+              <a href="element/node.jsp?node=<%=event.getNodeId()%>"><%=WebSecurityUtils.sanitizeString(event.getNodeLabel())%></a>
             <% } else {%>
               &nbsp;
             <% } %>
           </td>
           <c:if test="${acknowledgeEvent}">
diff --git a/opennms-webapp/src/main/webapp/WEB-INF/jsp/outage/detail.jsp b/opennms-webapp/src/main/webapp/WEB-INF/jsp/outage/detail.jsp
index 41640b564f2..f77f4d6607e 100644
--- a/opennms-webapp/src/main/webapp/WEB-INF/jsp/outage/detail.jsp
+++ b/opennms-webapp/src/main/webapp/WEB-INF/jsp/outage/detail.jsp
@@ -70,11 +70,11 @@
   <table class="table table-sm severity">
         <tr class="d-flex">
           <th class="col-2">Node</th>
           <td class="col-2">
             <% if( outage.getNodeId() > 0 ) { %>
-              <a href="element/node.jsp?node=<%=outage.getNodeId()%>"><%=outage.getNodeLabel()%></a>
+              <a href="element/node.jsp?node=<%=outage.getNodeId()%>"><%=WebSecurityUtils.sanitizeString(outage.getNodeLabel())%></a>
             <% } else {%>
               &nbsp;
             <% } %>
           </td>
           
diff --git a/opennms-webapp/src/main/webapp/admin/userGroupView/users/list.jsp b/opennms-webapp/src/main/webapp/admin/userGroupView/users/list.jsp
index b08f29698f4..c0d164c4e50 100644
--- a/opennms-webapp/src/main/webapp/admin/userGroupView/users/list.jsp
+++ b/opennms-webapp/src/main/webapp/admin/userGroupView/users/list.jsp
@@ -34,10 +34,14 @@
 	session="true"
 %>
 <%@page import="java.util.*" %>
 <%@page import="org.opennms.netmgt.config.*" %>
 <%@page import="org.opennms.netmgt.config.users.*" %>
+<%@ page import="org.opennms.core.utils.WebSecurityUtils" %>
+
+<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
+
 <%
 	UserManager userFactory;
   	Map<String,User> users = null;
 	
 	try
@@ -95,11 +99,11 @@
     {
         document.allUsers.userID.value=userID;
         var newID = prompt("Enter new name for user.", userID);
 
         if (newID != null && newID != "") {
-          if (/.*[&<>"`']+.*/.test(newId)) {
+          if (/.*[&<>"`']+.*/.test(newID)) {
             alert("The user ID must not contain any HTML markup.");
             return;
           }
 
           document.allUsers.newID.value = newID;
@@ -152,58 +156,59 @@
 	      String xmppAddress = userFactory.getXMPPAddress(userid);
 	      String numericService = userFactory.getNumericPage(userid);
 	      String textService = userFactory.getTextPage(userid);
 	      String numericPin = userFactory.getNumericPin(userid);
 	      String textPin = userFactory.getTextPin(userid);
+	      String sanitizedUserId = WebSecurityUtils.sanitizeString(curUser.getUserId());
          %>
          <tr id="user-<%= userid %>">
           <% if (!curUser.getUserId().equals("admin") && !curUser.getUserId().equals("rtc")) { %>
           <td rowspan="2" class="text-center"> 
-            <a id="<%= "users("+curUser.getUserId()+").doDelete" %>" href="javascript:deleteUser('<%=curUser.getUserId()%>')" onclick="return confirm('Are you sure you want to delete the user <%=curUser.getUserId()%>?')"><i class="fa fa-trash-o fa-2x"></i></a> 
+            <a id="<%= "users("+sanitizedUserId+").doDelete" %>" href="javascript:deleteUser('<%=sanitizedUserId%>')" onclick="return confirm('Are you sure you want to delete the user <%=sanitizedUserId%>?')"><i class="fa fa-trash-o fa-2x"></i></a>
           </td>
           <% } else { %>
           <td rowspan="2" class="text-center">
             <i class="fa fa-trash-o fa-2x" onclick="alert('Sorry, the admin user cannot be deleted.')"></i>
           </td>
           <% } %>
           <td rowspan="2" class="text-center">
-            <a id="<%= "users("+curUser.getUserId()+").doModify" %>" href="javascript:modifyUser('<%=curUser.getUserId()%>')"><i class="fa fa-edit fa-2x"></i></a>
+            <a id="<%= "users("+sanitizedUserId+").doModify" %>" href="javascript:modifyUser('<%=sanitizedUserId%>')"><i class="fa fa-edit fa-2x"></i></a>
           </td>
           <td rowspan="2" class="text-center">
             <% if ( !curUser.getUserId().equals("admin")) { %>
-                <button id="<%= "users("+curUser.getUserId()+").doRename" %>" class="btn btn-secondary"  name="rename" onclick="renameUser('<%=curUser.getUserId()%>')">Rename</button>
+                <button id="<%= "users("+sanitizedUserId+").doRename" %>" class="btn btn-secondary"  name="rename" onclick="renameUser('<%=sanitizedUserId%>')">Rename</button>
               <% } else { %>
-                <button id="<%= "users("+curUser.getUserId()+").doRename" %>" class="btn btn-secondary"  name="rename" onclick="alert('Sorry, the admin user cannot be renamed.')">Rename</button>
+                <button id="<%= "users("+sanitizedUserId+").doRename" %>" class="btn btn-secondary"  name="rename" onclick="alert('Sorry, the admin user cannot be renamed.')">Rename</button>
               <% } %>
           </td>
           <td>
-            <a id="<%= "users("+curUser.getUserId()+").doDetails" %>" href="javascript:detailUser('<%=curUser.getUserId()%>')"><%=curUser.getUserId()%></a>
+            <a id="<%= "users("+sanitizedUserId+").doDetails" %>" href="javascript:detailUser('<%=sanitizedUserId%>')"><%=sanitizedUserId%></a>
           </td>
           <td>
-           <div id="<%= "users("+curUser.getUserId()+").fullName" %>">
+           <div id="<%= "users("+sanitizedUserId+").fullName" %>">
 		    <%= (curUser.getFullName().orElse("")) %>
 	      </div>
           </td>
           <td>
-            <div id="<%= "users("+curUser.getUserId()+").email" %>">
+            <div id="<%= "users("+sanitizedUserId+").email" %>">
             <%= ((email == null || email.equals("")) ? "&nbsp;" : email) %>
             </div>
           </td>
           <td>
-           <div id="<%= "users("+curUser.getUserId()+").pagerEmail" %>">
+           <div id="<%= "users("+sanitizedUserId+").pagerEmail" %>">
             <%= ((pagerEmail == null || pagerEmail.equals("")) ? "&nbsp;" : pagerEmail) %>
             </div>
           </td>
           <td>
-           <div id="<%= "users("+curUser.getUserId()+").xmppAddress" %>">
+           <div id="<%= "users("+sanitizedUserId+").xmppAddress" %>">
             <%= ((xmppAddress == null || xmppAddress.equals("")) ? "&nbsp;" : xmppAddress) %>
            </div>
           </td>
           </tr>
           <tr>
             <td colspan="5">
-             <div id="<%= "users("+curUser.getUserId()+").userComments" %>">
+             <div id="<%= "users("+sanitizedUserId+").userComments" %>">
              <%= (curUser.getUserComments().orElse("No Comments")) %>
 	        </div>
             </td>
           </tr>
          <% row++;
diff --git a/opennms-webapp/src/main/webapp/admin/userGroupView/users/modifyUser.jsp b/opennms-webapp/src/main/webapp/admin/userGroupView/users/modifyUser.jsp
index 2c02c352a6a..04814d2ab99 100644
--- a/opennms-webapp/src/main/webapp/admin/userGroupView/users/modifyUser.jsp
+++ b/opennms-webapp/src/main/webapp/admin/userGroupView/users/modifyUser.jsp
@@ -38,10 +38,11 @@
 <%@page import="java.time.ZoneId"%>
 <%@page import="org.opennms.netmgt.config.*"%>
 <%@page import="org.opennms.netmgt.config.users.*"%>
 <%@page import="org.opennms.web.api.Util"%>
 <%@page import="org.opennms.web.api.Authentication"%>
+<%@ page import="org.opennms.core.utils.WebSecurityUtils" %>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 
 <%!
     private String createSelectList(String name, List<String> elements) {
         StringBuffer buffer = new StringBuffer("<select class=\"form-control\" multiple=\"multiple\" name=\""+name+"\" size=\"10\">");
@@ -251,19 +252,19 @@
         document.modifyUser.submit();
     }
 </script>
 
 <form role="form" class="form-horizontal" id="modifyUser" method="post" name="modifyUser">
-<input id="userID" type="hidden" name="userID" value="<%=user.getUserId()%>"/>
+<input id="userID" type="hidden" name="userID" value="<%=WebSecurityUtils.sanitizeString(user.getUserId())%>"/>
 <input id="password" type="hidden" name="password"/>
 <input id="redirect" type="hidden" name="redirect"/>
 
 <div class="row">
   <div class="col-md-6">
     <div class="card">
       <div class="card-header">
-        <span>Modify User: <%=userid%></span>
+        <span>Modify User: <%=WebSecurityUtils.sanitizeString(userid)%></span>
       </div>
       <div class="card-body">
         <h3>User Password</h3>
           <div class="form-group">
             <button type="button" class="btn btn-secondary" onClick="resetPassword()">Reset Password</button>
diff --git a/opennms-webapp/src/main/webapp/admin/userGroupView/users/userDetail.jsp b/opennms-webapp/src/main/webapp/admin/userGroupView/users/userDetail.jsp
index a9412e05cd4..7b0ce9c2f54 100644
--- a/opennms-webapp/src/main/webapp/admin/userGroupView/users/userDetail.jsp
+++ b/opennms-webapp/src/main/webapp/admin/userGroupView/users/userDetail.jsp
@@ -37,10 +37,12 @@
 		java.text.*,
 		org.opennms.netmgt.config.users.*,
 		org.opennms.web.servlet.MissingParameterException
 	"
 %>
+<%@ page import="org.opennms.core.utils.WebSecurityUtils" %>
+<%@ page import="java.util.stream.Collectors" %>
 
 <%
 	User user = null;
 	UserManager userFactory = UserFactory.getInstance();
   	String userID = request.getParameter("userID");
@@ -70,11 +72,11 @@
 
 <div class="row">
   <div class="col-md-6">
     <div class="card">
       <div class="card-header">
-        <span>Details for User: <%=user.getUserId()%></span>
+        <span>Details for User: <%=WebSecurityUtils.sanitizeString(user.getUserId())%></span>
       </div>
       <table class="table table-sm">
         <tr>
           <th>
             Full Name:
diff --git a/opennms-webapp/src/main/webapp/notification/detail.jsp b/opennms-webapp/src/main/webapp/notification/detail.jsp
index 539311768a1..445cfd0943a 100644
--- a/opennms-webapp/src/main/webapp/notification/detail.jsp
+++ b/opennms-webapp/src/main/webapp/notification/detail.jsp
@@ -112,11 +112,11 @@
           &nbsp;
         </c:otherwise>
       </c:choose>
     </td>
     <th class="col-md-1">Responder</th>
-    <td class="col-md-2"><%=notice.getResponder()!=null ? notice.getResponder() : "&nbsp;"%></td>
+    <td class="col-md-2"><%=notice.getResponder()!=null ? WebSecurityUtils.sanitizeString(notice.getResponder()) : "&nbsp;"%></td>
     <th class="col-md-1">Location</th>
     <td class="col-md-2">
       <c:choose>
         <c:when test="<%= eventLocation != null %>">
           <a href="event/detail.jsp?id=<%=notice.getEventId()%>"><%= eventLocation %></a>
@@ -235,11 +235,11 @@
     </tr>
   
   <%  for (NoticeSentTo sentTo : notice.getSentTo()) { %>
 
     <tr class="severity-<%=eventSeverity.toLowerCase()%>">
-      <td><%=sentTo.getUserId()%></td>
+      <td><%=WebSecurityUtils.sanitizeString(sentTo.getUserId())%></td>
 
       <td>
         <c:choose>
           <c:when test="<%=sentTo.getTime() != null && sentTo.getTime().getTime() > 0%>">
             <onms:datetime date="<%=sentTo.getTime()%>" />

Vulnerable code:         <span>Details for Group: <%=group.getName()%></span>
            <%=group.getComments()%>
               <li> <%=user%> </li>
         <tr class="divider ${groupStatus.index % 2 == 0 ?  'even' : 'odd'}" id="group-${group.name}">
              <c:when test='${group.name != "Admin"}'>
                <a id="${group.name}.doDelete" href="javascript:deleteGroup('${group.name}')" onclick="return confirm('Are you sure you want to delete the group ${group.name}?')"><i class="fa fa-trash-o fa-2x"></i></a>              
                <i class="fa fa-trash-o fa-2x" onclick="alert('Sorry, the ${group.name} group cannot be deleted.')"></i>
            <a id="${group.name}.doModify" href="javascript:modifyGroup('${group.name}')"><i class="fa fa-edit fa-2x"></i></a>
                <button id="${group.name}.doRename" type="button" class="btn btn-secondary" name="rename" onclick="renameGroup('${group.name}')">Rename</button>
                <button id="${group.name}.doRename" type="button" class="btn btn-secondary" name="rename" onclick="alert('Sorry, the Admin group cannot be renamed.')">Rename</button>
            <a href="javascript:detailGroup('${group.name}')">${group.name}</a>
                  ${group.comments.get()}
            buffer.append("<option>" + category + "</option>");
        <td><%=ack.getAckUser()%></td>
              <a href="element/node.jsp?node=<%=event.getNodeId()%>"><%=event.getNodeLabel()%></a>
              <a href="element/node.jsp?node=<%=outage.getNodeId()%>"><%=outage.getNodeLabel()%></a>
          if (/.*[&<>"`']+.*/.test(newId)) {
            <a id="<%= "users("+curUser.getUserId()+").doDelete" %>" href="javascript:deleteUser('<%=curUser.getUserId()%>')" onclick="return confirm('Are you sure you want to delete the user <%=curUser.getUserId()%>?')"><i class="fa fa-trash-o fa-2x"></i></a> 
            <a id="<%= "users("+curUser.getUserId()+").doModify" %>" href="javascript:modifyUser('<%=curUser.getUserId()%>')"><i class="fa fa-edit fa-2x"></i></a>
                <button id="<%= "users("+curUser.getUserId()+").doRename" %>" class="btn btn-secondary"  name="rename" onclick="renameUser('<%=curUser.getUserId()%>')">Rename</button>
                <button id="<%= "users("+curUser.getUserId()+").doRename" %>" class="btn btn-secondary"  name="rename" onclick="alert('Sorry, the admin user cannot be renamed.')">Rename</button>
            <a id="<%= "users("+curUser.getUserId()+").doDetails" %>" href="javascript:detailUser('<%=curUser.getUserId()%>')"><%=curUser.getUserId()%></a>
           <div id="<%= "users("+curUser.getUserId()+").fullName" %>">
            <div id="<%= "users("+curUser.getUserId()+").email" %>">
           <div id="<%= "users("+curUser.getUserId()+").pagerEmail" %>">
           <div id="<%= "users("+curUser.getUserId()+").xmppAddress" %>">
             <div id="<%= "users("+curUser.getUserId()+").userComments" %>">
<input id="userID" type="hidden" name="userID" value="<%=user.getUserId()%>"/>
        <span>Modify User: <%=userid%></span>
        <span>Details for User: <%=user.getUserId()%></span>
    <td class="col-md-2"><%=notice.getResponder()!=null ? notice.getResponder() : "&nbsp;"%></td>
      <td><%=sentTo.getUserId()%></td>
Fixed code: <%@ page import="org.opennms.core.utils.WebSecurityUtils" %>
        <span>Details for Group: <%=WebSecurityUtils.sanitizeString(group.getName())%></span>
            <%=WebSecurityUtils.sanitizeString(group.getComments())%>
               <li> <%=WebSecurityUtils.sanitizeString(user)%> </li>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
         <tr class="divider ${groupStatus.index % 2 == 0 ?  'even' : 'odd'}" id="group-${fn:escapeXml(group.name)}">
              <c:when test='${fn:escapeXml(group.name) != "Admin"}'>
                <a id="${group.name}.doDelete" href="javascript:deleteGroup('${fn:escapeXml(group.name)}')" onclick="return confirm('Are you sure you want to delete the group ${fn:escapeXml(group.name)}?')"><i class="fa fa-trash-o fa-2x"></i></a>
                <i class="fa fa-trash-o fa-2x" onclick="alert('Sorry, the ${fn:escapeXml(group.name)} group cannot be deleted.')"></i>
            <a id="${fn:escapeXml(group.name)}.doModify" href="javascript:modifyGroup('${fn:escapeXml(group.name)}')"><i class="fa fa-edit fa-2x"></i></a>
                <button id="${fn:escapeXml(group.name)}.doRename" type="button" class="btn btn-secondary" name="rename" onclick="renameGroup('${fn:escapeXml(group.name)}')">Rename</button>
                <button id="${fn:escapeXml(group.name)}.doRename" type="button" class="btn btn-secondary" name="rename" onclick="alert('Sorry, the Admin group cannot be renamed.')">Rename</button>
            <a href="javascript:detailGroup('${fn:escapeXml(group.name)}')">${fn:escapeXml(group.name)}</a>
                  ${fn:escapeXml(group.comments.get())}
<%@ page import="org.opennms.core.utils.WebSecurityUtils" %>
            buffer.append("<option>" + WebSecurityUtils.sanitizeString(category) + "</option>");
        <td><%=WebSecurityUtils.sanitizeString(ack.getAckUser())%></td>
              <a href="element/node.jsp?node=<%=event.getNodeId()%>"><%=WebSecurityUtils.sanitizeString(event.getNodeLabel())%></a>
              <a href="element/node.jsp?node=<%=outage.getNodeId()%>"><%=WebSecurityUtils.sanitizeString(outage.getNodeLabel())%></a>
<%@ page import="org.opennms.core.utils.WebSecurityUtils" %>

<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

          if (/.*[&<>"`']+.*/.test(newID)) {
	      String sanitizedUserId = WebSecurityUtils.sanitizeString(curUser.getUserId());
            <a id="<%= "users("+sanitizedUserId+").doDelete" %>" href="javascript:deleteUser('<%=sanitizedUserId%>')" onclick="return confirm('Are you sure you want to delete the user <%=sanitizedUserId%>?')"><i class="fa fa-trash-o fa-2x"></i></a>
            <a id="<%= "users("+sanitizedUserId+").doModify" %>" href="javascript:modifyUser('<%=sanitizedUserId%>')"><i class="fa fa-edit fa-2x"></i></a>
                <button id="<%= "users("+sanitizedUserId+").doRename" %>" class="btn btn-secondary"  name="rename" onclick="renameUser('<%=sanitizedUserId%>')">Rename</button>
                <button id="<%= "users("+sanitizedUserId+").doRename" %>" class="btn btn-secondary"  name="rename" onclick="alert('Sorry, the admin user cannot be renamed.')">Rename</button>
            <a id="<%= "users("+sanitizedUserId+").doDetails" %>" href="javascript:detailUser('<%=sanitizedUserId%>')"><%=sanitizedUserId%></a>
           <div id="<%= "users("+sanitizedUserId+").fullName" %>">
            <div id="<%= "users("+sanitizedUserId+").email" %>">
           <div id="<%= "users("+sanitizedUserId+").pagerEmail" %>">
           <div id="<%= "users("+sanitizedUserId+").xmppAddress" %>">
             <div id="<%= "users("+sanitizedUserId+").userComments" %>">
<%@ page import="org.opennms.core.utils.WebSecurityUtils" %>
<input id="userID" type="hidden" name="userID" value="<%=WebSecurityUtils.sanitizeString(user.getUserId())%>"/>
        <span>Modify User: <%=WebSecurityUtils.sanitizeString(userid)%></span>
<%@ page import="org.opennms.core.utils.WebSecurityUtils" %>
<%@ page import="java.util.stream.Collectors" %>
        <span>Details for User: <%=WebSecurityUtils.sanitizeString(user.getUserId())%></span>
    <td class="col-md-2"><%=notice.getResponder()!=null ? WebSecurityUtils.sanitizeString(notice.getResponder()) : "&nbsp;"%></td>
      <td><%=WebSecurityUtils.sanitizeString(sentTo.getUserId())%></td>