Commit 7113b1a4 authored by DJ Mountney's avatar DJ Mountney

Merge branch 'cherry-pick-dc2ac993' into 'security-9-2'

Escapes html content before appending it to the DOM

See merge request !2107
parent e9002222
...@@ -1478,7 +1478,7 @@ const normalizeNewlines = function(str) { ...@@ -1478,7 +1478,7 @@ const normalizeNewlines = function(str) {
const cachedNoteBodyText = $noteBodyText.html(); const cachedNoteBodyText = $noteBodyText.html();
// Show updated comment content temporarily // Show updated comment content temporarily
$noteBodyText.html(formContent); $noteBodyText.html(_.escape(formContent));
$editingNote.removeClass('is-editing fade-in-full').addClass('being-posted fade-in-half'); $editingNote.removeClass('is-editing fade-in-full').addClass('being-posted fade-in-half');
$editingNote.find('.note-headline-meta a').html('<i class="fa fa-spinner fa-spin" aria-label="Comment is being updated" aria-hidden="true"></i>'); $editingNote.find('.note-headline-meta a').html('<i class="fa fa-spinner fa-spin" aria-label="Comment is being updated" aria-hidden="true"></i>');
...@@ -1491,7 +1491,7 @@ const normalizeNewlines = function(str) { ...@@ -1491,7 +1491,7 @@ const normalizeNewlines = function(str) {
}) })
.fail(() => { .fail(() => {
// Submission failed, revert back to original note // Submission failed, revert back to original note
$noteBodyText.html(cachedNoteBodyText); $noteBodyText.html(_.escape(cachedNoteBodyText));
$editingNote.removeClass('being-posted fade-in'); $editingNote.removeClass('being-posted fade-in');
$editingNote.find('.fa.fa-spinner').remove(); $editingNote.find('.fa.fa-spinner').remove();
......
...@@ -461,6 +461,45 @@ import '~/notes'; ...@@ -461,6 +461,45 @@ import '~/notes';
}); });
}); });
describe('update comment with script tags', () => {
const sampleComment = '<script></script>';
const updatedComment = '<script></script>';
const note = {
id: 1234,
html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
<div class="note-text">${sampleComment}</div>
</li>`,
note: sampleComment,
valid: true
};
let $form;
let $notesContainer;
beforeEach(() => {
this.notes = new Notes('', []);
window.gon.current_username = 'root';
window.gon.current_user_fullname = 'Administrator';
$form = $('form.js-main-target-form');
$notesContainer = $('ul.main-notes-list');
$form.find('textarea.js-note-text').html(sampleComment);
});
it('should not render a script tag', () => {
const deferred = $.Deferred();
spyOn($, 'ajax').and.returnValue(deferred.promise());
$('.js-comment-button').click();
deferred.resolve(note);
const $noteEl = $notesContainer.find(`#note_${note.id}`);
$noteEl.find('.js-note-edit').click();
$noteEl.find('textarea.js-note-text').html(updatedComment);
$noteEl.find('.js-comment-save-button').click();
const $updatedNoteEl = $notesContainer.find(`#note_${note.id}`).find('.js-task-list-container');
expect($updatedNoteEl.find('.note-text').text().trim()).toEqual('');
});
});
describe('getFormData', () => { describe('getFormData', () => {
let $form; let $form;
let sampleComment; let sampleComment;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment