mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-29 20:16:44 +00:00
Merge pull request from GHSA-rm89-9g65-4ffr
* Enable HTML escaping for all tables by default * Enable HTML escaping for all tables by default * Adds automatic escaping for bootstrap tables where custom formatter function is specified - Intercept the row data *before* it is provided to the renderer function - Adds a function for sanitizing nested data structure * Sanitize form data before processing
This commit is contained in:
parent
57563f6b7a
commit
cd418d6948
@ -13,6 +13,7 @@
|
|||||||
inventreeDocReady,
|
inventreeDocReady,
|
||||||
inventreeLoad,
|
inventreeLoad,
|
||||||
inventreeSave,
|
inventreeSave,
|
||||||
|
sanitizeData,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function attachClipboard(selector, containerselector, textElement) {
|
function attachClipboard(selector, containerselector, textElement) {
|
||||||
@ -273,6 +274,40 @@ function loadBrandIcon(element, name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to sanitize a (potentially nested) object.
|
||||||
|
* Iterates through all levels, and sanitizes each primitive string.
|
||||||
|
*
|
||||||
|
* Note that this function effectively provides a "deep copy" of the provided data,
|
||||||
|
* and the original data structure is unaltered.
|
||||||
|
*/
|
||||||
|
function sanitizeData(data) {
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
} else if (Array.isArray(data)) {
|
||||||
|
// Handle arrays
|
||||||
|
var ret = [];
|
||||||
|
data.forEach(function(val) {
|
||||||
|
ret.push(sanitizeData(val));
|
||||||
|
});
|
||||||
|
} else if (typeof(data) === 'object') {
|
||||||
|
// Handle nested structures
|
||||||
|
var nested = {};
|
||||||
|
$.each(data, function(k, v) {
|
||||||
|
nested[k] = sanitizeData(v);
|
||||||
|
});
|
||||||
|
|
||||||
|
return nested;
|
||||||
|
} else if (typeof(data) === 'string') {
|
||||||
|
// Perform string replacement
|
||||||
|
return data.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/`/g, '`');
|
||||||
|
} else {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Convenience function to determine if an element exists
|
// Convenience function to determine if an element exists
|
||||||
$.fn.exists = function() {
|
$.fn.exists = function() {
|
||||||
return this.length !== 0;
|
return this.length !== 0;
|
||||||
|
@ -204,6 +204,9 @@ function constructChangeForm(fields, options) {
|
|||||||
},
|
},
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
|
|
||||||
|
// Ensure the data are fully sanitized before we operate on it
|
||||||
|
data = sanitizeData(data);
|
||||||
|
|
||||||
// An optional function can be provided to process the returned results,
|
// An optional function can be provided to process the returned results,
|
||||||
// before they are rendered to the form
|
// before they are rendered to the form
|
||||||
if (options.processResults) {
|
if (options.processResults) {
|
||||||
|
@ -381,6 +381,8 @@ $.fn.inventreeTable = function(options) {
|
|||||||
// Extract query params
|
// Extract query params
|
||||||
var filters = options.queryParams || options.filters || {};
|
var filters = options.queryParams || options.filters || {};
|
||||||
|
|
||||||
|
options.escape = true;
|
||||||
|
|
||||||
// Store the total set of query params
|
// Store the total set of query params
|
||||||
options.query_params = filters;
|
options.query_params = filters;
|
||||||
|
|
||||||
@ -567,6 +569,49 @@ function customGroupSorter(sortName, sortOrder, sortData) {
|
|||||||
|
|
||||||
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['en-US-custom']);
|
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['en-US-custom']);
|
||||||
|
|
||||||
|
// Enable HTML escaping by default
|
||||||
|
$.fn.bootstrapTable.escape = true;
|
||||||
|
|
||||||
|
// Override the 'calculateObjectValue' function at bootstrap-table.js:3525
|
||||||
|
// Allows us to escape any nasty HTML tags which are rendered to the DOM
|
||||||
|
$.fn.bootstrapTable.utils._calculateObjectValue = $.fn.bootstrapTable.utils.calculateObjectValue;
|
||||||
|
|
||||||
|
$.fn.bootstrapTable.utils.calculateObjectValue = function escapeCellValue(self, name, args, defaultValue) {
|
||||||
|
|
||||||
|
var args_list = [];
|
||||||
|
|
||||||
|
if (args) {
|
||||||
|
|
||||||
|
args_list.push(args[0]);
|
||||||
|
|
||||||
|
if (name && typeof(name) === 'function' && name.name == 'formatter') {
|
||||||
|
/* This is a custom "formatter" function for a particular cell,
|
||||||
|
* which may side-step regular HTML escaping, and inject malicious code into the DOM.
|
||||||
|
*
|
||||||
|
* Here we have access to the 'args' supplied to the custom 'formatter' function,
|
||||||
|
* which are in the order:
|
||||||
|
* args = [value, row, index, field]
|
||||||
|
*
|
||||||
|
* 'row' is the one we are interested in
|
||||||
|
*/
|
||||||
|
|
||||||
|
var row = Object.assign({}, args[1]);
|
||||||
|
|
||||||
|
args_list.push(sanitizeData(row));
|
||||||
|
} else {
|
||||||
|
args_list.push(args[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var ii = 2; ii < args.length; ii++) {
|
||||||
|
args_list.push(args[ii]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = $.fn.bootstrapTable.utils._calculateObjectValue(self, name, args_list, defaultValue);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
||||||
$.extend($.fn.treegrid.defaults, {
|
$.extend($.fn.treegrid.defaults, {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user