Skip to content

Commit

Permalink
NMS-13231: Backport Security Issues from Last Month
Browse files Browse the repository at this point in the history
  • Loading branch information
christianpape committed Apr 20, 2021
1 parent b6a8557 commit eb08b5e
Show file tree
Hide file tree
Showing 31 changed files with 233 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ require('../services/Requisitions');
RequisitionsService.startTiming();
RequisitionsService.saveForeignSourceDefinition($scope.foreignSourceDef).then(
function() { // success
growl.success('The definition for the requisition ' + $scope.foreignSource + ' has been saved.');
growl.success('The definition for the requisition ' + _.escape($scope.foreignSource) + ' has been saved.');
form.$dirty = false;
},
$scope.errorHandler
Expand All @@ -474,7 +474,7 @@ require('../services/Requisitions');
RequisitionsService.startTiming();
RequisitionsService.deleteForeignSourceDefinition($scope.foreignSource).then(
function() { // success
growl.success('The foreign source definition for ' + $scope.foreignSource + 'has been reseted.');
growl.success('The foreign source definition for ' + _.escape($scope.foreignSource) + 'has been reseted.');
$scope.initialize();
},
$scope.errorHandler
Expand Down Expand Up @@ -517,7 +517,7 @@ require('../services/Requisitions');
* @methodOf ForeignSourceController
*/
$scope.initialize = function() {
growl.success('Retrieving definition for requisition ' + $scope.foreignSource + '...');
growl.success('Retrieving definition for requisition ' + _.escape($scope.foreignSource) + '...');
RequisitionsService.getForeignSourceDefinition($scope.foreignSource).then(
function(foreignSourceDef) { // success
$scope.foreignSourceDef = foreignSourceDef;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ const RequisitionMetaDataEntry = require('../model/RequisitionMetaDataEntry');
RequisitionsService.startTiming();
RequisitionsService.saveNode($scope.node).then(
function() { // success
growl.success('The node ' + $scope.node.nodeLabel + ' has been saved.');
growl.success('The node ' + _.escape($scope.node.nodeLabel) + ' has been saved.');
$scope.foreignId = $scope.node.foreignId;
form.$dirty = false;
},
Expand All @@ -492,7 +492,7 @@ const RequisitionMetaDataEntry = require('../model/RequisitionMetaDataEntry');
* @methodOf NodeController
*/
$scope.refresh = function() {
growl.success('Retrieving node ' + $scope.foreignId + ' from requisition ' + $scope.foreignSource + '...');
growl.success('Retrieving node ' + _.escape($scope.foreignId) + ' from requisition ' + _.escape($scope.foreignSource) + '...');
RequisitionsService.getNode($scope.foreignSource, $scope.foreignId).then(
function(node) { // success
$scope.node = node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ const QuickNode = require('../model/QuickNode');
*/
$scope.provision = function() {
$scope.isSaving = true;
growl.info($sanitize('The node ' + $scope.node.nodeLabel + ' is being added to requisition ' + $scope.node.foreignSource + '. Please wait...'));
var successMessage = $sanitize('The node ' + $scope.node.nodeLabel + ' has been added to requisition ' + $scope.node.foreignSource);
growl.info('The node ' + _.escape($scope.node.nodeLabel) + ' is being added to requisition ' + _.escape($scope.node.foreignSource) + '. Please wait...');
var successMessage = 'The node ' + _.escape($scope.node.nodeLabel) + ' has been added to requisition ' + _.escape($scope.node.foreignSource);
RequisitionsService.quickAddNode($scope.node).then(
function() { // success
$scope.reset();
Expand Down Expand Up @@ -238,7 +238,7 @@ const QuickNode = require('../model/QuickNode');
function() { // success
RequisitionsService.synchronizeRequisition(foreignSource, false).then(
function() {
growl.success('The requisition ' + foreignSource + ' has been created and synchronized.');
growl.success('The requisition ' + _.escape(foreignSource) + ' has been created and synchronized.');
$scope.foreignSources.push(foreignSource);
},
$scope.errorHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ require('../services/Synchronize');
* @param {object} The node's object to delete
*/
$scope.deleteNode = function(node) {
bootbox.confirm('Are you sure you want to remove the node ' + node.nodeLabel + '?', function(ok) {
bootbox.confirm('Are you sure you want to remove the node ' + _.escape(node.nodeLabel) + '?', function(ok) {
if (ok) {
RequisitionsService.startTiming();
RequisitionsService.deleteNode(node).then(
Expand All @@ -214,7 +214,7 @@ require('../services/Synchronize');
if (index > -1) {
$scope.filteredNodes.splice(index,1);
}
growl.success('The node ' + node.nodeLabel + ' has been deleted.');
growl.success('The node ' + _.escape(node.nodeLabel) + ' has been deleted.');
},
$scope.errorHandler
);
Expand Down Expand Up @@ -295,7 +295,7 @@ require('../services/Synchronize');
if (value) {
$scope.pageSize = value;
}
growl.success('Retrieving requisition ' + $scope.foreignSource + '...');
growl.success('Retrieving requisition ' + _.escape($scope.foreignSource) + '...');
RequisitionsService.getRequisition($scope.foreignSource).then(
function(requisition) { // success
$scope.requisition = requisition;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,14 @@ require('../services/Synchronize');
}
});
modalInstance.result.then(function(targetForeignSource) {
bootbox.confirm('This action will override the existing foreign source definition for the requisition named ' + targetForeignSource + ', using ' + foreignSource + ' as a template. Are you sure you want to continue ? This cannot be undone.', function(ok) {
bootbox.confirm('This action will override the existing foreign source definition for the requisition named ' + _.escape(targetForeignSource) + ', using ' + _.escape(foreignSource) + ' as a template. Are you sure you want to continue ? This cannot be undone.', function(ok) {
if (!ok) {
return;
}
RequisitionsService.startTiming();
RequisitionsService.cloneForeignSourceDefinition(foreignSource, targetForeignSource).then(
function() { // success
growl.success('The foreign source definition for ' + foreignSource + ' has been cloned to ' + targetForeignSource);
growl.success('The foreign source definition for ' + _.escape(foreignSource) + ' has been cloned to ' + _.escape(targetForeignSource));
},
$scope.errorHandler
);
Expand All @@ -201,18 +201,18 @@ require('../services/Synchronize');
if (foreignSource) {
// Validate Requisition
if (foreignSource.match(/[/\\?:&*'"]/)) {
bootbox.alert('Cannot add the requisition ' + foreignSource + ' because the following characters are invalid:<br/>:, /, \\, ?, &, *, \', "');
bootbox.alert('Cannot add the requisition ' + _.escape(foreignSource) + ' because the following characters are invalid:<br/>:, /, \\, ?, &, *, \', "');
return;
}
var r = $scope.requisitionsData.getRequisition(foreignSource);
if (r) {
bootbox.alert('Cannot add the requisition ' + foreignSource+ ' because there is already a requisition with that name');
bootbox.alert('Cannot add the requisition ' + _.escape(foreignSource) + ' because there is already a requisition with that name');
return;
}
// Create Requisition
RequisitionsService.addRequisition(foreignSource).then(
function(r) { // success
growl.success('The requisition ' + r.foreignSource + ' has been created.');
growl.success('The requisition ' + _.escape(r.foreignSource) + ' has been created.');
},
$scope.errorHandler
);
Expand Down Expand Up @@ -271,7 +271,7 @@ require('../services/Synchronize');
RequisitionsService.startTiming();
RequisitionsService.updateDeployedStatsForRequisition(requisition).then(
function() { // success
growl.success('The deployed statistics for ' + requisition.foreignSource + ' has been updated.');
growl.success('The deployed statistics for ' + _.escape(requisition.foreignSource) + ' has been updated.');
},
$scope.errorHandler
);
Expand All @@ -286,12 +286,12 @@ require('../services/Synchronize');
* @param {string} foreignSource The name of the requisition
*/
$scope.removeAllNodes = function(foreignSource) {
bootbox.confirm('Are you sure you want to remove all the nodes from ' + foreignSource + '?', function(ok) {
bootbox.confirm('Are you sure you want to remove all the nodes from ' + _.escape(foreignSource) + '?', function(ok) {
if (ok) {
RequisitionsService.startTiming();
RequisitionsService.removeAllNodesFromRequisition(foreignSource).then(
function() { // success
growl.success('All the nodes from ' + foreignSource + ' have been removed, and the requisition has been synchronized.');
growl.success('All the nodes from ' + _.escape(foreignSource) + ' have been removed, and the requisition has been synchronized.');
var req = $scope.requisitionsData.getRequisition(foreignSource);
req.reset();
},
Expand All @@ -310,12 +310,12 @@ require('../services/Synchronize');
* @param {string} foreignSource The name of the requisition
*/
$scope.delete = function(foreignSource) {
bootbox.confirm('Are you sure you want to remove the requisition ' + foreignSource + '?', function(ok) {
bootbox.confirm('Are you sure you want to remove the requisition ' + _.escape(foreignSource) + '?', function(ok) {
if (ok) {
RequisitionsService.startTiming();
RequisitionsService.deleteRequisition(foreignSource).then(
function() { // success
growl.success('The requisition ' + foreignSource + ' has been deleted.');
growl.success('The requisition ' + _.escape(foreignSource) + ' has been deleted.');
},
$scope.errorHandler
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ require('./Requisitions');
RequisitionsService.startTiming();
RequisitionsService.synchronizeRequisition(requisition.foreignSource, rescanExisting).then(
function() { // success
growl.success('The import operation has been started for ' + requisition.foreignSource + ' (rescanExisting? ' + rescanExisting + ')<br/>Use <b>refresh</b> to update the deployed statistics');
growl.success('The import operation has been started for ' + _.escape(requisition.foreignSource) + ' (rescanExisting? ' + rescanExisting + ')<br/>Use <b>refresh</b> to update the deployed statistics');
requisition.setDeployed(true);
},
errorHandler
Expand All @@ -58,7 +58,7 @@ require('./Requisitions');
'Choose <b>no</b> to synchronize only the new and deleted nodes with the database executing the scan phase only for new nodes.<br/>' +
'Choose <b>dbonly</b> to synchronize all the nodes with the database skipping the scan phase.<br/>' +
'Choose <b>cancel</b> to abort the request.',
title: 'Synchronize Requisition ' + requisition.foreignSource,
title: 'Synchronize Requisition ' + _.escape(requisition.foreignSource),
buttons: {
fullSync: {
label: 'Yes',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
'use strict';

const angular = require('angular-js');
const _ = require('underscore-js');
require('angular-mocks');
require('../../../../../src/main/assets/js/apps/onms-requisitions/requisitions');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
'use strict';

const angular = require('angular-js');
const _ = require('underscore-js');
require('angular-mocks');
require('../../../../../src/main/assets/js/apps/onms-requisitions/requisitions');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
'use strict';

const angular = require('angular-js');
const _ = require('underscore-js');
require('angular-mocks');
require('../../../../../src/main/assets/js/apps/onms-requisitions/requisitions');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
'use strict';

const angular = require('angular-js');
const _ = require('underscore-js');
require('angular-mocks');
require('../../../../../src/main/assets/js/apps/onms-requisitions/requisitions');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr
UserManager userFactory = UserFactory.getInstance();

String userID = request.getParameter("userID");

if (userID != null && userID.matches(".*[&<>\"`']+.*")) {
throw new ServletException("User ID must not contain any HTML markup.");
}

String password = request.getParameter("pass1");

boolean hasUser = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public void doPost(HttpServletRequest request, HttpServletResponse response) thr
String userID = request.getParameter("userID");
String newID = request.getParameter("newID");

if (newID != null && newID.matches(".*[&<>\"`']+.*")) {
throw new ServletException("User ID must not contain any HTML markup.");
}

// now save to the xml file
try {
UserManager userFactory = UserFactory.getInstance();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,11 @@ private ModelAndView renameGroup(HttpServletRequest request, HttpServletResponse

String oldName = request.getParameter("groupName");
String newName = request.getParameter("newName");


if (newName != null && newName.matches(".*[&<>\"`']+.*")) {
throw new ServletException("Group ID must not contain any HTML markup.");
}

if (StringUtils.hasText(oldName) && StringUtils.hasText(newName)) {
m_groupRepository.renameGroup(oldName, newName);
}
Expand Down Expand Up @@ -312,6 +316,14 @@ private ModelAndView addGroup(HttpServletRequest request, HttpServletResponse re
groupComment = "";
}

if (groupName != null && groupName.matches(".*[&<>\"`']+.*")) {
throw new ServletException("Group ID must not contain any HTML markup.");
}

if (groupComment != null && groupComment.matches(".*[&<>\"`']+.*")) {
throw new ServletException("Group comment must not contain any HTML markup.");
}

boolean hasGroup = false;
try {
hasGroup = m_groupRepository.groupExists(groupName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%@ taglib uri="https://www.owasp.org/index.php/OWASP_Java_Encoder_Project" prefix="e"%>

<jsp:include page="/includes/bootstrap.jsp" flush="false" >
<jsp:param name="title" value="Event Notifications" />
Expand Down Expand Up @@ -109,31 +110,31 @@
<c:forEach items="${notifications}" var="notification">
<tr>
<td>
<input type="button" class="btn btn-secondary" value="Edit" onclick="javascript:editNotice('${notification.escapedName}')"/>
<input type="button" class="btn btn-secondary" value="Edit" onclick="javascript:editNotice('${e:forJavaScript(notification.escapedName)}')"/>
</td>
<td>
<input type="button" class="btn btn-secondary" value="Delete" onclick="javascript:deleteNotice('${notification.escapedName}')"/>
<input type="button" class="btn btn-secondary" value="Delete" onclick="javascript:deleteNotice('${e:forJavaScript(notification.escapedName)}')"/>
</td>
<td>
<c:choose>
<c:when test="${notification.isOn}">
<input type="radio" value="Off" onclick="javascript:setStatus('${notification.escapedName}','off')"/>Off
<input type="radio" value="On" CHECKED onclick="javascript:setStatus('${notification.escapedName}','on')"/>On
<input type="radio" value="Off" onclick="javascript:setStatus('${e:forJavaScript(notification.escapedName)}','off')"/>Off
<input type="radio" value="On" CHECKED onclick="javascript:setStatus('${e:forJavaScript(notification.escapedName)}','on')"/>On
</c:when>
<c:otherwise>
<input type="radio" value="Off" CHECKED onclick="javascript:setStatus('${notification.escapedName}','off')"/>Off
<input type="radio" value="On" onclick="javascript:setStatus('${notification.escapedName}','on')"/>On
<input type="radio" value="Off" CHECKED onclick="javascript:setStatus('${e:forJavaScript(notification.escapedName)}','off')"/>Off
<input type="radio" value="On" onclick="javascript:setStatus('${e:forJavaScript(notification.escapedName)}','on')"/>On
</c:otherwise>
</c:choose>
</td>
<td>
${notification.name}
${fn:escapeXml(notification.name)}
</td>
<td>
${notification.eventLabel}
${fn:escapeXml(notification.eventLabel)}
</td>
<td>
${notification.displayUei}
${fn:escapeXml(notification.displayUei)}
</td>
</tr>
</c:forEach>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
%>

<%@page import="org.opennms.web.group.WebGroup"%>
<%@ page import="org.opennms.core.utils.WebSecurityUtils" %>

<%
WebGroup group = (WebGroup)request.getAttribute("group");
Expand All @@ -60,13 +61,13 @@
<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>
Expand All @@ -79,7 +80,7 @@
<% } else { %>
<ul class="list-unstyled">
<% for (String user : users) { %>
<li> <%=user%> </li>
<li> <%=WebSecurityUtils.sanitizeString(user)%> </li>
<% } %>
</ul>
<% } %>
Expand Down
Loading

0 comments on commit eb08b5e

Please sign in to comment.