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:
parent
9dcc4fb79f
commit
bd4d377cf0
3 changed files with 48 additions and 32 deletions
|
@ -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
|
@ -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 );
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue