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(''));
});
});
});