Sanitizing HTML Content in RadEditor During Paste Operations
Environment
Product | RadEditor for ASP.NET AJAX |
Description
In RadEditor for ASP.NET AJAX, users can paste HTML content via the "Paste HTML" dialog or manually with Ctrl+V
. While the RadEditor RemoveScripts, StripDomEventAttributes, StripCssExpressions content filters prevent XSS attacks by sanitizing the content upon submission and on the server side, some users may wish to sanitize the content at the time of pasting. This article explains how to sanitize HTML content during paste operations in the OnClientPasteHtml event as well as in the Paste HTML dialog.
Solution
Sanitizing HTML Content During OnClientPasteHtml Event
To sanitize the HTML content during the OnClientPasteHtml event
, you can use the following JavaScript code in your RadEditor configuration:
<telerik:RadEditor runat="server" ID="RadEditor1" Height="600px" OnClientPasteHtml="OnClientPasteHtml" ContentFilters="DefaultFilters,StripDomEventAttributes">
</telerik:RadEditor>
<script>
function OnClientPasteHtml(editor, args) {
var content = args.get_value();
content = stripDomEventAttributes(content);
args.set_value(content);
}
function stripDomEventAttributes(html) {
var dummyElement = document.createElement('div');
dummyElement.innerHTML = html;
// Clean the dummy element
cleanElement(dummyElement);
// Remove script tags using regular expressions
var sanitizedHtml = dummyElement.innerHTML.replace(/<(SCRIPT)([^>]*)\/>/ig, '');
sanitizedHtml = sanitizedHtml.replace(/<(SCRIPT)([^>]*)>[\s\S]*?<\/(SCRIPT)([^>]*)>/ig, '');
// Return the sanitized HTML
return sanitizedHtml;
}
function cleanElement(element) {
var EXPRESSION_PATTERN = /expression\s*\(.*?\)/gi;
var eventAttributes = [
'onabort', 'onactivate', 'onafterprint', 'onauxclick', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onblur', 'oncanplay', 'oncanplaythrough', 'onchange', 'onclick', 'oncontextmenu', 'oncopy', 'oncuechange', 'oncut', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onfocus', 'onfocusin', 'onfocusout', 'ongotpointercapture', 'onhashchange', 'onhelp', 'oninput', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onloadeddata', 'onloadedmetadata', 'onloadstart', 'onlostpointercapture', 'onmessage', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmscontentzoom', 'onmsgesturechange', 'onmsgesturedoubletap', 'onmsgestureend', 'onmsgesturehold', 'onmsgesturestart', 'onmsgesturetap', 'onmsgotpointercapture', 'onmsinertiastart', 'onmslostpointercapture', 'onmsmanipulationstatechanged', 'onmspointercancel', 'onmspointerdown', 'onmspointerenter', 'onmspointerleave', 'onmspointermove', 'onmspointerout', 'onmspointerover', 'onmspointerup', 'onoffline', 'ononline', 'onpagehide', 'onpageshow', 'onpaste', 'onpause', 'onplay', 'onplaying', 'onpointercancel', 'onpointerdown', 'onpointerenter', 'onpointerleave', 'onpointermove', 'onpointerout', 'onpointerover', 'onpointerup', 'onpopstate', 'onprogress', 'onratechange', 'onreset', 'onresize', 'onscroll', 'onseeked', 'onseeking', 'onselect', 'onselectstart', 'onstalled', 'onstorage', 'onsubmit', 'onsuspend', 'ontimeupdate', 'ontoggle', 'onunload', 'onvolumechange', 'onwaiting', 'onwheel'
];
if (element.nodeType === Node.ELEMENT_NODE) {
eventAttributes.forEach(function (attr) {
element.removeAttribute(attr);
});
if ((element.tagName === 'IFRAME' || element.tagName === 'IMG') && element.src.indexOf('javascript:') === 0) {
element.removeAttribute('src');
}
if (element.style) {
element.style.cssText = element.style.cssText.replace(EXPRESSION_PATTERN, '');
}
if (element.hasAttribute('style') && element.getAttribute('style').trim() === '') {
element.removeAttribute('style');
}
var children = element.children;
for (var i = 0; i < children.length; i++) {
cleanElement(children[i]);
}
}
}
</script>
Sanitizing HTML Content in the Paste HTML Dialog
The solution above also applies to the content inserted (pasted) by the Paste HTML
since its content goes through the OnClientPasteHtml event.
Summary
By implementing these modifications, you ensure that HTML content pasted into RadEditor is sanitized immediately, providing an additional layer of security against potential XSS attacks. Although the built-in content filters are effective, this approach offers real-time protection during paste operations, enhancing the overall security of your application.