Stored Cross-site Scripting in Client's Name #1727

This commit is contained in:
Hillel Coren 2017-10-30 16:00:55 +02:00
parent 5e7f6a029b
commit dbd19d4174
12 changed files with 42 additions and 52 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -460,7 +460,7 @@ if (window.ko) {
function comboboxHighlighter(item) {
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
var result = item.replace(new RegExp('<br/>', 'g'), "\n");
result = stripHtmlTags(result);
result = _.escape(result);
result = result.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
return match ? '<strong>' + match + '</strong>' : query;
});
@ -476,17 +476,6 @@ function inIframe () {
}
}
function comboboxMatcher(item) {
return ~stripHtmlTags(item).toLowerCase().indexOf(this.query.toLowerCase());
}
function stripHtmlTags(text) {
// http://stackoverflow.com/a/5002618/497368
var div = document.createElement("div");
div.innerHTML = text;
return div.textContent || div.innerText || '';
}
function getContactDisplayName(contact)
{
if (contact.first_name || contact.last_name) {
@ -563,7 +552,7 @@ function populateInvoiceComboboxes(clientId, invoiceId) {
$clientSelect.val(clientId);
}
$clientSelect.combobox();
$clientSelect.combobox({highlighter: comboboxHighlighter});
$clientSelect.on('change', function(e) {
var clientId = $('input[name=client]').val();
var invoiceId = $('input[name=invoice]').val();
@ -602,7 +591,7 @@ function populateInvoiceComboboxes(clientId, invoiceId) {
}
});
$invoiceSelect.combobox();
$invoiceSelect.combobox({highlighter: comboboxHighlighter});
if (invoiceId) {
var invoice = invoiceMap[invoiceId];

View File

@ -381,7 +381,7 @@ iframe.src = '{{ rtrim(SITE_URL ,'/') }}/view/'
$productSelect.append(new Option(formatMoney(product.cost) + ' - ' + product.product_key, product.public_id));
}
$productSelect.combobox();
$productSelect.combobox({highlighter: comboboxHighlighter});
fixCheckboxes();
updateBuyNowButtons();

View File

@ -80,7 +80,7 @@
$clientSelect.val({{ $clientPublicId }});
}
$clientSelect.combobox();
$clientSelect.combobox({highlighter: comboboxHighlighter});
@endif
$('#currency_id').combobox();

View File

@ -350,7 +350,7 @@
}
$clientSelect.append(new Option(clientName, client.public_id));
}
$clientSelect.combobox().change(function() {
$clientSelect.combobox({highlighter: comboboxHighlighter}).change(function() {
onClientChange();
});

View File

@ -113,7 +113,7 @@
{!! Former::select('client')
->addOption('', '')
->data_bind("dropdown: client, dropdownOptions: {highlighter: comboboxHighlighter, matcher: comboboxMatcher}")
->data_bind("dropdown: client, dropdownOptions: {highlighter: comboboxHighlighter}")
->addClass('client-input')
->addGroupClass('client_select closer-row') !!}

View File

@ -1006,10 +1006,10 @@ ko.bindingHandlers.productTypeahead = {
limit: 50,
templates: {
suggestion: function(item) { return '<div title="'
+ item.product_key + ': '
+ _.escape(item.product_key) + ': '
+ item.cost + "\n"
+ item.notes.substring(0, 60) + '">'
+ item.product_key + '</div>' }
+ _.escape(item.product_key) + '</div>' }
},
source: searchData(allBindings.items, allBindings.key)
}).on('typeahead:select', function(element, datum, name) {

View File

@ -7,8 +7,9 @@ ${{ $entityType }}Select.combobox({
return "{{ trans("texts.create_{$entityType}") }}: " + this.query;
} else {
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
item = _.escape(item);
return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
return '<strong>' + match + '</strong>';
return match ? '<strong>' + match + '</strong>' : query;
})
}
},

View File

@ -80,7 +80,7 @@
$clientSelect.val({{ $clientPublicId }});
@endif
$clientSelect.combobox();
$clientSelect.combobox({highlighter: comboboxHighlighter});
@if ($clientPublicId)
$('#name').focus();

View File

@ -566,7 +566,7 @@
$clientSelect.val(clientId);
}
$clientSelect.combobox();
$clientSelect.combobox({highlighter: comboboxHighlighter});
$clientSelect.on('change', function(e) {
var clientId = $('input[name=client]').val();
var projectId = $('input[name=project_id]').val();

View File

@ -205,12 +205,12 @@
{!! Former::select('client_id')
->addOption('', '')
->label('client')
->data_bind("dropdown: selectedTask().client_id") !!}
->data_bind("dropdown: selectedTask().client_id, dropdownOptions: {highlighter: comboboxHighlighter}") !!}
</div>
<div style="padding-bottom: 20px; padding-left:6px;" class="project-select col-md-6 no-padding-mobile">
{!! Former::select('project_id')
->addOption('', '')
->data_bind("dropdown: selectedTask().project_id")
->data_bind("dropdown: selectedTask().project_id, dropdownOptions: {highlighter: comboboxHighlighter}")
->label(trans('texts.project')) !!}
</div>
</div>
@ -395,7 +395,7 @@
function refreshClientList() {
var $clientSelect = $('select#client_id');
$clientSelect.find('option').remove().end().combobox('refresh');
$clientSelect.combobox({highlighter: comboboxHighlighter}).find('option').remove().end().combobox('refresh');
$clientSelect.append(new Option('', ''));
@if (Auth::user()->can('create', ENTITY_CLIENT))