CVE-2021-25933: 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 `groupName` and `groupComment` parameters. Due to this flaw, an authenticated attacker could inject arbitrary script and trick other admin users into downloading malicious files which can cause severe damage to the organization using opennms.
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: 4.8
Published: 2021-05-20T15: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 623c9bc5c76b..de4c0c8efe8c 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 4d9734b52687..03c093acaa8c 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 c70e61e3487f..b4fc9a574cd4 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 cb6d70aa2cfc..523863ed912d 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 79caff231d4f..726ad12e22ec 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 41640b564f2f..f77f4d6607ec 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 b08f29698f41..c0d164c4e509 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 2c02c352a6a4..04814d2ab995 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 a9412e05cd4c..7b0ce9c2f548 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 539311768a1a..445cfd0943a6 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>