diff --git a/modules/clipboard.js b/modules/clipboard.js index 6b816bc1ea..9d8db33ef1 100644 --- a/modules/clipboard.js +++ b/modules/clipboard.js @@ -84,8 +84,11 @@ class Clipboard extends Module { } else if (!html) { return new Delta().insert(text || ''); } - const container = this.quill.root.ownerDocument.createElement('div'); - container.innerHTML = html.replace(/>\r?\n +<'); // Remove spaces between tags + const doc = new DOMParser().parseFromString( + html.replace(/>\r?\n +<'), // Remove spaces between tags + 'text/html', + ); + const container = doc.body; const nodeMatches = new WeakMap(); const [elementMatchers, textMatchers] = this.prepareMatching( container, diff --git a/test/unit/modules/clipboard.js b/test/unit/modules/clipboard.js index 037c8d0bd9..a6b14948de 100644 --- a/test/unit/modules/clipboard.js +++ b/test/unit/modules/clipboard.js @@ -262,11 +262,20 @@ describe('Clipboard', function() { expect(delta).toEqual(expected); }); + it('does not execute javascript', function() { + window.unsafeFunction = jasmine.createSpy('unsafeFunction'); + const html = + ""; + this.clipboard.convert({ html }); + expect(window.unsafeFunction).not.toHaveBeenCalled(); + delete window.unsafeFunction; + }); + it('xss', function() { const delta = this.clipboard.convert({ html: '', }); - expect(delta).toEqual(new Delta().insert('alert(2);')); + expect(delta).toEqual(new Delta().insert('')); }); }); });