If the user insert an Iframe in the Html mode of RadEditor, switch to Design mode and then switch back to Html mode, the HTML content becomes non-editable. The issue is reproducible in Chrome. Possible workaround: Use the RadEditor control in Div content mode: http://demos.telerik.com/aspnet-ajax/editor/examples/contentareamodediv/defaultcs.aspx
A page which exhibits the error is included below. I have a ticket open with Chromium as well: https://code.google.com/p/chromium/issues/detail?id=412772&thanks=412772&ts=1410359622 Problematic page: http://imodblue.imodules.com/s/1197/social.aspx?sid=1197&gid=1&pgid=2219&content_id=1815 (click the Registration button) Only crashes when the RadEditor is referenced on the page, even if it remains hidden. I'm working on trying to strip it down to a simpler example, but maybe the full page is enough for you guys to help me diagnose it. We are on an older version in production, 2012.3.1023.35. The crash was reproducible with version 2014.2.724.45, but there's no public site with that version that I can use as an example.
When using the Flash Manager to add a flash object into the content, causes the HTML mode to be non editable. The following example code is a possible workaround for this behavior: <telerik:RadEditor ID="RadEditor1" runat="server" OnClientModeChange="OnClientModeChange"> </telerik:RadEditor> <script type="text/javascript"> function OnClientModeChange(editor, args) { var $ = $telerik.$, mode = editor.get_mode(), contentAreaElement = editor.get_contentArea(), editorModes = Telerik.Web.UI.EditModes; if (mode === editorModes.Html) { $(contentAreaElement).hide(); } else { $(contentAreaElement).show(); } } </script>
Update:
For securing the RadEditor content and preventing XSS attacks we advise enabling the RemoveScripts, EncodeScripts, StripCssExpressions and StripDomEventAttributes content filters to sanitize the content. For more information please check the following help article and blog post on the matter:
Original message:
It is possible to conduct a successful XSS attack by injecting a specific malicious content in the RadEditor content. This attack targets Internet explorer browsers. It takes advantage of a security vulnerability related to the CSS expression rule in Legacy IE browsers, where arbitrary JavaScript code embedded in the style attribute of a DOM element can be run on the page. There is a workaround that is strongly recommended to be used in order to make such attack attempts unsuccessful. The idea is to strip the expression declaration from the style attribute value of DOM elements in the RadEditor Content. Following is a sample implementation Usage: protected void Page_Load(object sender, EventArgs e) { var sanitizer = new CssExpressionSanitizer(); theEditor.Content = sanitizer.Sanitize(theEditor.Content); } Content of the CssExpressionSanitizer class: public class CssExpressionSanitizer { private static readonly Regex expressionPattern = new Regex(@"<[a-zA-Z0-9]+[^>]*?style=['""]?.*?(?<cssRule>[^;""]+: expression(?<bracket>\())", RegexOptions.Compiled); public string Sanitize(string input) { var matches = expressionPattern.Matches(input); for (int i = matches.Count - 1; i >= 0; i--) { input = SanitizeExpression(input, matches[i]); } return input; } private string SanitizeExpression(string input, Match m) { var cssRuleIndex = m.Groups["cssRule"].Index; var expressionIndex = m.Groups["bracket"].Index; input = StripMatchingBracketsWithContent(input, expressionIndex); input = input.Remove(cssRuleIndex, expressionIndex - cssRuleIndex); if (input[cssRuleIndex] == ';') { input = input.Remove(cssRuleIndex, 1); } return input; } private string StripMatchingBracketsWithContent(string input, int startIndex) { var openBrackets = 0; do { char currentChar = input[startIndex]; if (currentChar == '"' || currentChar == '\'' || currentChar == '/') { //strip within quotation marks making sure brackets appearing in string constructs do not interfere with the counting var parser = new InPairStringParser(currentChar); input = parser.Sanitize(input, startIndex); currentChar = input[startIndex]; } input = input.Remove(startIndex, 1); if (currentChar == '(') openBrackets++; else if (currentChar == ')') openBrackets--; } while (openBrackets > 0 && input.Length > startIndex); return input; } public class InPairStringParser { public InPairStringParser(char pairChar) { this.pattern = new Regex(String.Format("{0}.*?(?<!\\\\){0}", pairChar)); } public string Sanitize(string input, int startIndex) { var subinput = input.Substring(startIndex); return input.Substring(0, startIndex) + pattern.Replace(subinput, "", 1); } private readonly Regex pattern; } }
Having the entity in a sentence, and trying to find or find and replace in this sentence, the found word seem to be incorrectly highlighted/selected. Therefore, when trying to replace, incorrect selection is replaced. A possible fix is adding the entities inside span elements, so that additional inner text nodes are created. The following code example implements such functionality upon opening and closing the FindAndReplace dialog <telerik:RadEditor ID="RadEditor1" runat="server" OnClientCommandExecuted="OnClientCommandExecuted"> <Content> <p>some text. some text.</p> </Content> </telerik:RadEditor> <script type="text/javascript"> function OnClientCommandExecuted(editor, args) { var commandName = args.get_commandName(); if ($telerik.isIE && commandName === "FindAndReplace") { updateNbspEntities(editor, true); var dialog = editor.get_dialogOpener()._dialogContainers[commandName]; dialog.add_close(function () { updateNbspEntities(editor, false); }); } }; function updateNbspEntities(editor, toAddInNodes) { var html = editor.get_html(true); if (toAddInNodes) { // insert all entities inside nodes to fix IE ranges html = html.replace(/(( )+)/gi, "<span>$1</span>"); } else { // restore them when FindAndReplace dialog is closed html = html.replace(/<span>(( )+)<\/span>|<font>(( )+)<\/font>/gi, "$1"); } editor.set_html(html); }; </script>
Steps to reproduce: 1. Create StyleSheet.css file containing the following style: p { color: red; } 2. Set the following markup: <telerik:RadWindow ID="RadWindow1" runat="server" VisibleOnPageLoad="true"> <ContentTemplate> <telerik:RadEditor ID="RadEditor1" runat="server"> <CssFiles> <telerik:EditorCssFile Value="StyleSheet.css" /> </CssFiles> <Content> <p>test</p> <p>test</p> </Content> </telerik:RadEditor> </ContentTemplate> </telerik:RadWindow> 3. Make sure RadEditor's EditorCssFile property points to the created StyleSheet.css file Result: The red color is not applied to the paragraphs in the content area. Workaround: <script> (function (utils) { var addStyleSheet = utils.addStyleSheet; utils.addStyleSheet = function (url, doc, id) { if ($telerik.isFirefox) { if (!url) return; doc = doc || document; var link = doc.createElement("link"); link.setAttribute("href", url, 0); link.setAttribute("type", "text/css"); link.setAttribute("rel", "stylesheet", 0); if (id) link.setAttribute("id", id); var headElement = doc.getElementsByTagName("head")[0]; var addSheet = function () { headElement.appendChild(link); }; window.setTimeout(addSheet, 200); } else { addStyleSheet.call(this, url, doc, id); } } })(Telerik.Web.UI.Editor.Utils); </script>
When user selects an image in the RadEditor resize handles appear. When resizing or replacing the image, the same handles still appear at the initial position. This confuse the users that the image is not selected and leave an incorrect trace of the resize handles.
When importing external video in RadEditor, the video in the embedding code does not have the option to use https. The dialog could detect the protocol from the video to be imported and use it in the generated code at the end.
When you use the ApplyClass command to set CSS classes to selections in a paragraph element in the content of RadEditor, the CSS class is applied to the whole paragraph.
When ToolbarMode is set to "RibbonBarFloating" the RadEditor height becomes greater than the control height. As a result the wrapper overlaps with the elements box below. As a temporary workaround for ToolbarMode="RibbonBarFloating" only, the following JavaScript code need to be applied on the page: <script type="text/javascript"> (function () { var getToolbarHeight = Telerik.Web.UI.Editor.UI.DimensionsCalculator.prototype._getToolbarHeight; Telerik.Web.UI.Editor.UI.DimensionsCalculator.prototype._getToolbarHeight = function (container) { var $container = $telerik.$(container); $container.append($container.find("div")); return getToolbarHeight.call(this, container); } })(); </script>
The issue is reproducible when NewLineMode is Br and the cursor is at the end of the formatting node in Chrome. The workaround is to check the position of the new inserted Br element and append it to the formatting node if it is necessary. <telerik:RadEditor ID="RadEditor1" runat="server" NewLineMode="Br"> </telerik:RadEditor> <script type="text/javascript"> (function () { if (!$telerik.isChrome) return; var insertBr = Telerik.Web.UI.Editor.EnterNewLineCommand.prototype._insertBrElementSafari; Telerik.Web.UI.Editor.EnterNewLineCommand.prototype._insertBrElementSafari = function () { var utils = Telerik.Web.UI.Editor.Utils, command = this, selection = command.get_editor().getSelection(), range = selection.getRange(); if (range.commonAncestorContainer != range.startContainer || range.commonAncestorContainer != range.endContainer) return insertBr.call(command); var commonElement = utils.isTextNode(range.commonAncestorContainer) ? range.commonAncestorContainer.parentNode : range.commonAncestorContainer; var commandResult = insertBr.call(command); range = selection.getRange(); var br = range.commonAncestorContainer.childNodes[range.startOffset]; if (!utils.isTag(br, "br")) return commandResult; if (!$telerik.$.contains(commonElement, br)) { commonElement.appendChild(br); range.selectNodeContents(commonElement); range.collapse(false); selection.selectRange(range); } return commandResult; } })(); </script>
Steps: 1. Add some track changes text using Author=User0 and UserCSSId="reU0". 2. Change the Author to "User1" and UserCSSId to "reU1". 3. Click inside of User0's tracked text and start typing. Results: The new text is displayed as if User0 wrote it, in User0's color. Expected Result: The new text that was injected by User1 in the middle of User0's text would be have User1's color and hover text that pertains to User1. (Similar to how Word does it.)
When there are list items which are links, pressing enter to create new list item duplicates the previously created anchor. The same issue applies when new lines are created with link inside.
Spell Checking throws JS error on a subsequent opening of the spell checking dialog. You can resolve this by forcing the IE11 browser to IE10 compatibility mode. <meta http-equiv="X-UA-Compatible" content="IE=10" />
When using the built-in AJAX Spell Checker of the Editor, on the first misspelled word the corresponding popup opens. When the user finishes with the first word, the same popup should open for the following word, but under IE11 this does not happen and the user is forced to click on the word for the dialog to open. To resolve this you can force the IE11 browser to IE10 compatibility mode with a meta tag in the head element pf the page <meta http-equiv="X-UA-Compatible" content="IE=10" />
The floating toolbar window does not open when the user toggles to full screen. You can resolve the issue by incorporating the following script block: <telerik:RadEditor runat="server" ID="RadEditor1" ToolbarMode="Floating"></telerik:RadEditor> <script type="text/javascript"> Telerik.Web.UI.Editor.DefaultToolAdapter.prototype._showToolbarHolder = function (isVisible) { var editor = this.get_editor(); var toolbarEnum = Telerik.Web.UI.EditorToolbarMode; if (!isVisible) { if (this._toolbarHolder) this._toolbarHolder.hide(); //NEW - Add a check for the toolbar holder return; } //Hide if in fullscreen mode and toolbar is ShowOnFocus if (editor.isFullScreen() && editor.get_toolbarMode() === Telerik.Web.UI.EditorToolbarMode.ShowOnFocus ) return; //Hide previous wrapper and mark yourself as the wrapper var wrapper = Telerik.Web.UI.Editor.DefaultToolAdapter._visibleWrapper; //Return if you are already visible if (wrapper == this && wrapper._toolbarHolder && wrapper._toolbarHolder.isVisible())//NEW - toolbar holder might not be created! { //Activete it before returning, as it could have been deactivated after showing an editor dialog wrapper.get_toolbarHolder().setActive(true); return; } if (wrapper && wrapper._showToolbarHolder) wrapper._showToolbarHolder(false); Telerik.Web.UI.Editor.DefaultToolAdapter._visibleWrapper = this; //Create the holder in the last possible moment before showing this.get_window(); //Do additional initialization depending on toolbar mode this._initNonDefaultToolbarMode(); //Show toolbar hodler this._toolbarHolder.show(); //IE, ShowOnFocus, PageTop: hide properly the fake toolbar parent here instead _moveToolbarsToEditor if ($telerik.isIE) { var toolbarMode = editor.get_toolbarMode(); switch (toolbarMode) { case toolbarEnum.ShowOnFocus: case toolbarEnum.PageTop: editor.get_TopZone().firstChild.style.display = "none"; break; } } }; </script>
Such tools exist in Word 2013 - 'Show Markup' and 'Display for Review' tools. They are used by the users to be able to see the originally typed text, the final results (as if the track changes were accepted) and some further options for the visual appearance of the tracked text. Such option would be very useful in the RadEditor, because in a large text where multiple users would add their suggestion, redaction and comments, the text would go quite unordered and difficult to be handled with.
Clipboard operations are restricted in these browsers and when the paste tool is used nothing is happening. An alert should show up just like the Copy and Cut tools are designed. A possible workaround is using the same functionality as the Cut command by incorporating the following JavaScript line of code <telerik:RadEditor ID="RadEditor1" runat="server"> </telerik:RadEditor> <script type="text/javascript"> Telerik.Web.UI.Editor.CommandList["Paste"] = Telerik.Web.UI.Editor.CommandList["Cut"]; </script>
When typing text, user tries to change the font-size or font-name a span element is added into the content with the chosen formatting options, but new text is not added into the span but outside. Due to that the applied formatting does not affect the new text typed in the RadEditor.