diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2017-05-25 14:32:14 +0100 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2017-05-25 14:32:14 +0100 |
commit | dc2ac9937a378f4351ba34bb6fab93558f93d611 (patch) | |
tree | dd1b842005418cfe76db8c5a5f717680c3ad0cf3 | |
parent | c013d23d6320487cf293891f7c6b213cab816980 (diff) | |
download | gitlab-ce-dc2ac9937a378f4351ba34bb6fab93558f93d611.tar.gz |
Escapes html content before appending it to the DOM
-rw-r--r-- | app/assets/javascripts/notes.js | 4 | ||||
-rw-r--r-- | changelogs/unreleased/32908-edit-comment.yml | 4 | ||||
-rw-r--r-- | spec/javascripts/notes_spec.js | 39 |
3 files changed, 45 insertions, 2 deletions
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index b0b1cfd6c8a..702915c516f 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -1398,7 +1398,7 @@ const normalizeNewlines = function(str) { const cachedNoteBodyText = $noteBodyText.html(); // 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.find('.note-headline-meta a').html('<i class="fa fa-spinner fa-spin" aria-label="Comment is being updated" aria-hidden="true"></i>'); @@ -1411,7 +1411,7 @@ const normalizeNewlines = function(str) { }) .fail(() => { // Submission failed, revert back to original note - $noteBodyText.html(cachedNoteBodyText); + $noteBodyText.html(_.escape(cachedNoteBodyText)); $editingNote.removeClass('being-posted fade-in'); $editingNote.find('.fa.fa-spinner').remove(); diff --git a/changelogs/unreleased/32908-edit-comment.yml b/changelogs/unreleased/32908-edit-comment.yml new file mode 100644 index 00000000000..5237dceed11 --- /dev/null +++ b/changelogs/unreleased/32908-edit-comment.yml @@ -0,0 +1,4 @@ +--- +title: Escapes html content before appending it to the DOM +merge_request: +author: diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index 025f08ee332..ccd703b5b4b 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -443,6 +443,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', () => { it('should return form metadata object from form reference', () => { this.notes = new Notes('', []); |