0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 15:23:29 -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,27 +3879,35 @@ 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 ) {
if ( isPaste ) { frag = DOMPurify.sanitize( html, {
startFragmentIndex = html.indexOf( '<!--StartFragment-->' ); WHOLE_DOCUMENT: false,
endFragmentIndex = html.lastIndexOf( '<!--EndFragment-->' ); RETURN_DOM: true,
if ( startFragmentIndex > -1 && endFragmentIndex > -1 ) { RETURN_DOM_FRAGMENT: true
html = html.slice( startFragmentIndex + 20, endFragmentIndex ); });
frag = doc.importNode( frag, true );
} else {
if ( isPaste ) {
startFragmentIndex = html.indexOf( '<!--StartFragment-->' );
endFragmentIndex = html.lastIndexOf( '<!--EndFragment-->' );
if ( startFragmentIndex > -1 && endFragmentIndex > -1 ) {
html = html.slice( startFragmentIndex + 20, endFragmentIndex );
}
} }
// Parse HTML into DOM tree
div = this.createElement( 'DIV' );
div.innerHTML = html;
frag = doc.createDocumentFragment();
frag.appendChild( empty( div ) );
} }
// Parse HTML into DOM tree
div.innerHTML = html;
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,27 +1611,35 @@ 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 ) {
if ( isPaste ) { frag = DOMPurify.sanitize( html, {
startFragmentIndex = html.indexOf( '<!--StartFragment-->' ); WHOLE_DOCUMENT: false,
endFragmentIndex = html.lastIndexOf( '<!--EndFragment-->' ); RETURN_DOM: true,
if ( startFragmentIndex > -1 && endFragmentIndex > -1 ) { RETURN_DOM_FRAGMENT: true
html = html.slice( startFragmentIndex + 20, endFragmentIndex ); });
frag = doc.importNode( frag, true );
} else {
if ( isPaste ) {
startFragmentIndex = html.indexOf( '<!--StartFragment-->' );
endFragmentIndex = html.lastIndexOf( '<!--EndFragment-->' );
if ( startFragmentIndex > -1 && endFragmentIndex > -1 ) {
html = html.slice( startFragmentIndex + 20, endFragmentIndex );
}
} }
// Parse HTML into DOM tree
div = this.createElement( 'DIV' );
div.innerHTML = html;
frag = doc.createDocumentFragment();
frag.appendChild( empty( div ) );
} }
// Parse HTML into DOM tree
div.innerHTML = html;
frag.appendChild( empty( div ) );
// Record undo checkpoint // Record undo checkpoint
this.saveUndoState( range ); this.saveUndoState( range );