0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2025-01-10 08:50:13 -05:00

Sanitise pasted HTML if DOMPurify library present.

This protects against malicious HTML being added to the clipboard, and also
removes unwanted content before insertion.

DOMPurify can be found at https://github.com/cure53/DOMPurify
This commit is contained in:
Neil Jenkins 2016-06-06 11:32:15 +10:00
parent 9dcc4fb79f
commit bd4d377cf0
3 changed files with 48 additions and 32 deletions

View file

@ -3879,15 +3879,21 @@ var addLinks = function ( frag, root, self ) {
// by the html being inserted. // by the html being inserted.
proto.insertHTML = function ( html, isPaste ) { proto.insertHTML = function ( html, isPaste ) {
var range = this.getSelection(); var range = this.getSelection();
var frag = this._doc.createDocumentFragment(); var doc = this._doc;
var div = this.createElement( 'DIV' );
var startFragmentIndex, endFragmentIndex; var startFragmentIndex, endFragmentIndex;
var root, node, event; var div, frag, root, node, event;
// Edge doesn't just copy the fragment, but includes the surrounding guff // Edge doesn't just copy the fragment, but includes the surrounding guff
// including the full <head> of the page. Need to strip this out. In the // including the full <head> of the page. Need to strip this out. If
// future should probably run all pastes through DOMPurify, but this will // available use DOMPurify to parse and sanitise.
// do for now if ( typeof DOMPurify !== 'undefined' && DOMPurify.isSupported ) {
frag = DOMPurify.sanitize( html, {
WHOLE_DOCUMENT: false,
RETURN_DOM: true,
RETURN_DOM_FRAGMENT: true
});
frag = doc.importNode( frag, true );
} else {
if ( isPaste ) { if ( isPaste ) {
startFragmentIndex = html.indexOf( '<!--StartFragment-->' ); startFragmentIndex = html.indexOf( '<!--StartFragment-->' );
endFragmentIndex = html.lastIndexOf( '<!--EndFragment-->' ); endFragmentIndex = html.lastIndexOf( '<!--EndFragment-->' );
@ -3895,10 +3901,12 @@ proto.insertHTML = function ( html, isPaste ) {
html = html.slice( startFragmentIndex + 20, endFragmentIndex ); html = html.slice( startFragmentIndex + 20, endFragmentIndex );
} }
} }
// Parse HTML into DOM tree // Parse HTML into DOM tree
div = this.createElement( 'DIV' );
div.innerHTML = html; div.innerHTML = html;
frag = doc.createDocumentFragment();
frag.appendChild( empty( div ) ); frag.appendChild( empty( div ) );
}
// Record undo checkpoint // Record undo checkpoint
this.saveUndoState( range ); this.saveUndoState( range );

File diff suppressed because one or more lines are too long

View file

@ -1611,15 +1611,21 @@ var addLinks = function ( frag, root, self ) {
// by the html being inserted. // by the html being inserted.
proto.insertHTML = function ( html, isPaste ) { proto.insertHTML = function ( html, isPaste ) {
var range = this.getSelection(); var range = this.getSelection();
var frag = this._doc.createDocumentFragment(); var doc = this._doc;
var div = this.createElement( 'DIV' );
var startFragmentIndex, endFragmentIndex; var startFragmentIndex, endFragmentIndex;
var root, node, event; var div, frag, root, node, event;
// Edge doesn't just copy the fragment, but includes the surrounding guff // Edge doesn't just copy the fragment, but includes the surrounding guff
// including the full <head> of the page. Need to strip this out. In the // including the full <head> of the page. Need to strip this out. If
// future should probably run all pastes through DOMPurify, but this will // available use DOMPurify to parse and sanitise.
// do for now if ( typeof DOMPurify !== 'undefined' && DOMPurify.isSupported ) {
frag = DOMPurify.sanitize( html, {
WHOLE_DOCUMENT: false,
RETURN_DOM: true,
RETURN_DOM_FRAGMENT: true
});
frag = doc.importNode( frag, true );
} else {
if ( isPaste ) { if ( isPaste ) {
startFragmentIndex = html.indexOf( '<!--StartFragment-->' ); startFragmentIndex = html.indexOf( '<!--StartFragment-->' );
endFragmentIndex = html.lastIndexOf( '<!--EndFragment-->' ); endFragmentIndex = html.lastIndexOf( '<!--EndFragment-->' );
@ -1627,10 +1633,12 @@ proto.insertHTML = function ( html, isPaste ) {
html = html.slice( startFragmentIndex + 20, endFragmentIndex ); html = html.slice( startFragmentIndex + 20, endFragmentIndex );
} }
} }
// Parse HTML into DOM tree // Parse HTML into DOM tree
div = this.createElement( 'DIV' );
div.innerHTML = html; div.innerHTML = html;
frag = doc.createDocumentFragment();
frag.appendChild( empty( div ) ); frag.appendChild( empty( div ) );
}
// Record undo checkpoint // Record undo checkpoint
this.saveUndoState( range ); this.saveUndoState( range );