Cross-Site Scripting vulnerability in CKSource CKEditor
Description
A Cross-Site scripting vulnerability has been found in CKSource CKEditor affecting versions 4.15.1 and earlier. An attacker could send malicious javascript code through the /ckeditor/samples/old/ajax.html file and retrieve an authorized user's information.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
CKEditor 4.15.1 and earlier are vulnerable to stored XSS via the /ckeditor/samples/old/ajax.html sample file, allowing an attacker to retrieve authorized user data.
A Cross-Site Scripting (XSS) vulnerability has been identified in CKEditor 4 versions 4.15.1 and earlier, specifically within the sample file /ckeditor/samples/old/ajax.html. This file is part of the CKEditor distribution's sample set, which is intended for demonstration and development purposes and should not be deployed in production environments. The root cause involves improper handling of text input during HTML parsing, as evidenced by the commit that modifies how CDATA sections are processed [1][3].
Exploitation requires an attacker to craft and send a malicious JavaScript payload through the vulnerable sample file. The attack does not require authentication, but relies on user interaction — specifically, a victim must visit the crafted URL while being logged into the CKEditor application. The vulnerability is classified as reflected XSS in the official advisory, though the sample file could also be used persistently if deployed [3][4].
If successfully exploited, an attacker can execute arbitrary JavaScript in the context of the victim's browser session. This can lead to disclosure of sensitive information (such as cookies or session tokens) belonging to an authorized user, thereby compromising session integrity and confidentiality. The CVSS v3.1 base score is 6.1 (Medium) with a vector of AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N [4].
CKEditor 4 reached its End of Life (EOL) on June 30, 2023, and the open-source version no longer receives security patches [2]. The commit referenced in the advisory patches the parsing logic [1], but users of EOL versions must either upgrade to CKEditor 4 LTS (commercial extended support) or, more importantly, remove all sample files from production deployments. The INCIBE advisory explicitly notes that the sample file is not intended for production use [4]. Migration to CKEditor 5 is also recommended for long-term security [2].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
ckeditor4npm | < 4.24.0-lts | 4.24.0-lts |
Affected products
2- CKSource/CKEditorv5Range: 0
Patches
132 files changed · +662 −112
core/htmlparser.js+20 −15 modified@@ -121,10 +121,7 @@ CKEDITOR.htmlParser = function() { if ( tagIndex > nextIndex ) { var text = html.substring( nextIndex, tagIndex ); - if ( cdata ) - cdata.push( text ); - else - this.onText( text ); + this.onText( text ); } nextIndex = this._.htmlPartsRegex.lastIndex; @@ -142,7 +139,7 @@ CKEDITOR.htmlParser = function() { if ( cdata && CKEDITOR.dtd.$cdata[ tagName ] ) { // Send the CDATA data. - this.onCDATA( cdata.join( '' ) ); + this.onCDATA( cdata ); cdata = null; } @@ -152,20 +149,15 @@ CKEDITOR.htmlParser = function() { } } - // If CDATA is enabled, just save the raw match. - if ( cdata ) { - cdata.push( parts[ 0 ] ); - continue; - } - // Opening tag if ( ( tagName = parts[ 3 ] ) ) { tagName = tagName.toLowerCase(); // There are some tag names that can break things, so let's // simply ignore them when parsing. (https://dev.ckeditor.com/ticket/5224) - if ( /="/.test( tagName ) ) + if ( /="/.test( tagName ) ) { continue; + } var attribs = {}, attribMatch, @@ -186,9 +178,22 @@ CKEDITOR.htmlParser = function() { this.onTagOpen( tagName, attribs, selfClosing ); - // Open CDATA mode when finding the appropriate tags. - if ( !cdata && CKEDITOR.dtd.$cdata[ tagName ] ) - cdata = []; + // CDATA + if ( CKEDITOR.dtd.$cdata[ tagName ] ) { + var closingTagRegex = new RegExp( '<\/' + tagName + '>', 'i' ), + htmlPart = html.substring( nextIndex ), + closingTagIndex = htmlPart.search( closingTagRegex ); + + // If closing tag was not found, treat all remaining text as CDATA. + if ( closingTagIndex === -1 ) { + closingTagIndex = htmlPart.length; + } + + cdata = htmlPart.substring( 0, closingTagIndex ); + + this._.htmlPartsRegex.lastIndex = nextIndex + cdata.length; + nextIndex = this._.htmlPartsRegex.lastIndex; + } continue; }
plugins/autogrow/samples/autogrow.html+22 −0 modified@@ -64,6 +64,28 @@ <h1 class="samples"> <script> CKEDITOR.replace( 'editor1', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'autogrow', removePlugins: 'resize' });
plugins/devtools/samples/devtools.html+22 −0 modified@@ -64,6 +64,28 @@ <h1 class="samples"> // Replace the <textarea id="editor"> with an CKEditor // instance, using default configurations. CKEDITOR.replace( 'editor1', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'devtools' });
plugins/divarea/samples/divarea.html+21 −0 modified@@ -43,6 +43,27 @@ <h1 class="samples"> // Replace the <textarea id="editor"> with an CKEditor // instance, using default configurations. CKEDITOR.replace( 'editor1', { + plugins: [ + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'divarea' });
plugins/docprops/samples/docprops.html+15 −10 modified@@ -34,18 +34,13 @@ <h1 class="samples"> <pre class="samples"> CKEDITOR.replace( '<em>textarea_id</em>', { <strong>fullPage: true</strong>, - <strong>extraPlugins: 'docprops'</strong>, - <strong>allowedContent: true</strong> -}); + <strong>extraPlugins: 'docprops'</strong> +} ); </pre> <p> Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of the <code><textarea></code> element to be replaced. </p> - <p> - The <code><em>allowedContent</em></code> in the code above is set to <code>true</code> to disable content filtering. - Setting this option is not obligatory, but in full page mode there is a strong chance that one may want be able to freely enter any HTML content in source mode without any limitations. - </p> </div> <form action="../../../samples/sample_posteddata.php" method="post"> <label for="editor1"> @@ -59,9 +54,19 @@ <h1 class="samples"> CKEDITOR.replace( 'editor1', { fullPage: true, - extraPlugins: 'docprops', - allowedContent: true - }); + extraPlugins: 'docprops, wysiwygarea', + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); </script> <p>
plugins/enterkey/samples/enterkey.html+22 −0 modified@@ -24,6 +24,28 @@ // Create the editor again, with the appropriate settings. editor = CKEDITOR.replace( 'editor1', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'enterkey', enterMode: Number( document.getElementById( 'xEnter' ).value ), shiftEnterMode: Number( document.getElementById( 'xShiftEnter' ).value )
plugins/htmlwriter/samples/outputhtml.html+3 −1 modified@@ -147,7 +147,9 @@ <h1 class="samples"> on: { pluginsLoaded: configureTransformations, loaded: configureHtmlWriter - } + }, + + removePlugins: 'preview, print' }); /*
plugins/image2/samples/image2.html+21 −0 modified@@ -49,6 +49,27 @@ <h1 class="samples"> <script> CKEDITOR.replace( 'editor1', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools' + ], extraPlugins: 'image2', height: 450 } );
plugins/magicline/samples/magicline.html+48 −4 modified@@ -106,9 +106,31 @@ <h1 class="samples"> // window.onload event handler. CKEDITOR.replace( 'editor1', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image', + 'horizontalrule' + ], extraPlugins: 'magicline', // Ensure that magicline plugin, which is required for this sample, is loaded. - allowedContent: true // Switch off the ACF, so very complex content created to - // show magicline's power isn't filtered. + extraAllowedContent: 'div{*}' } ); </script> @@ -188,10 +210,32 @@ <h1 class="samples"> // window.onload event handler. CKEDITOR.replace( 'editor2', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image', + 'horizontalrule' + ], extraPlugins: 'magicline', // Ensure that magicline plugin, which is required for this sample, is loaded. magicline_color: 'blue', // Blue line - allowedContent: true // Switch off the ACF, so very complex content created to - // show magicline's power isn't filtered. + extraAllowedContent: 'div{*}' }); </script>
plugins/mathjax/samples/mathjax.html+41 −0 modified@@ -25,6 +25,47 @@ <h1 class="samples"> <div class="warning deprecated"> This sample is not maintained anymore. Check out its <a href="https://ckeditor.com/docs/ckeditor4/latest/examples/mathjax.html">brand new version in CKEditor Examples</a>. </div> + <form action="../../../samples/sample_posteddata.php" method="post"> + <div class="description"> + <p> + This editor allows displaying mathematical formulas, enabled by the <strong>Mathjax</strong> plugin. + </p> +<pre class="samples"> +CKEDITOR.replace( '<em>textarea_id</em>', { + extraPlugins: 'mathjax', + mathJaxLib: '<em><URL to the MathJax library></em>' +} );</pre> + </div> + <div id="editor1"> + <p>The following equations are represented in the HTML source code as LaTeX expressions.</p> + <h1>The Cauchy-Schwarz Inequality</h1> + <p><span class="math-tex">\( \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) \)</span></p> + <h1>The probability of getting <span class="math-tex">\(k\)</span> heads when flipping <span class="math-tex">\(n\)</span> coins is</h1> + <p><span class="math-tex">\(P(E) = {n \choose k} p^k (1-p)^{ n-k} \)</span></p> + <p>Finally, while displaying equations is useful for demonstration purposes, the ability to mix math and text in a paragraph is also important. This expression <span class="math-tex">\(\sqrt{3x-1}+(1+x)^2\)</span> is an example of an inline equation. As you see, MathJax equations can be used this way as well, without disturbing the spacing between the lines.</p> + </div> + <script> + + // This call can be placed at any point after the + // <textarea>, or inside a <head><script> in a + // window.onload event handler. + + // Replace the <textarea id="editor"> with an CKEditor + // instance, using default configurations. + CKEDITOR.replace( 'editor1', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'undo', + 'format' + ], + extraPlugins: 'mathjax', + mathJaxLib: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-AMS_HTML' + } ); + + </script> <div id="footer"> <hr> <p>
plugins/placeholder/samples/placeholder.html+22 −0 modified@@ -53,6 +53,28 @@ <h1 class="samples"> <script> CKEDITOR.replace( 'editor1', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'placeholder' });
plugins/sharedspace/samples/sharedspace.html+88 −0 modified@@ -68,6 +68,28 @@ <h3> CKEDITOR.disableAutoInline = true; CKEDITOR.inline( 'inline1', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'sharedspace', removePlugins: 'floatingspace,resize', sharedSpaces: { @@ -77,6 +99,28 @@ <h3> }); CKEDITOR.inline( 'inline2', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'sharedspace', removePlugins: 'floatingspace,resize', sharedSpaces: { @@ -86,6 +130,28 @@ <h3> }); CKEDITOR.appendTo( 'framed1', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'sharedspace', removePlugins: 'maximize,resize', sharedSpaces: { @@ -97,6 +163,28 @@ <h3> ); CKEDITOR.appendTo( 'framed2', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'sharedspace', removePlugins: 'maximize,resize', sharedSpaces: {
plugins/stylesheetparser/samples/stylesheetparser.html+22 −0 modified@@ -57,6 +57,28 @@ <h1 class="samples"> // Replace the <textarea id="editor"> with an CKEditor // instance, using default configurations. CKEDITOR.replace( 'editor1' , { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'stylesheetparser', // Stylesheet for the contents.
plugins/tableresize/samples/tableresize.html+22 −0 modified@@ -85,6 +85,28 @@ <h1 class="samples"> // Replace the <textarea id="editor"> with an CKEditor // instance, using default configurations. CKEDITOR.replace( 'editor1', { + plugins: [ + 'wysiwygarea', + 'sourcearea', + 'clipboard', + 'basicstyles', + 'pastefromword', + 'pastefromlibreoffice', + 'pastefromgdocs', + 'undo', + 'stylescombo', + 'format', + 'font', + 'colorbutton', + 'removeformat', + 'link', + 'list', + 'justify', + 'blockquote', + 'table', + 'tabletools', + 'image' + ], extraPlugins: 'tableresize' });
plugins/toolbar/samples/toolbar.html+26 −2 modified@@ -140,13 +140,37 @@ <h2 class="samples">Full toolbar configuration</h2> CKEDITOR.dom.element.createFromHtml( preOutput ).replace( pre ); } ); - CKEDITOR.replace( 'editorCurrent', { height: 100 } ); + CKEDITOR.replace( 'editorCurrent', { + height: 100, + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); CKEDITOR.replace( 'editorFull', { // Reset toolbar settings, so full toolbar will be generated automatically. toolbar: null, toolbarGroups: null, removeButtons: null, - height: 100 + height: 100, + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } } ); function dumpToolbarConfiguration( editor, printGroups ) {
plugins/wysiwygarea/samples/fullpage.html+14 −9 modified@@ -33,18 +33,13 @@ <h1 class="samples"> </p> <pre class="samples"> CKEDITOR.replace( '<em>textarea_id</em>', { - <strong>fullPage: true</strong>, - <strong>allowedContent: true</strong> + <strong>fullPage: true</strong> }); </pre> <p> Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of the <code><textarea></code> element to be replaced. </p> - <p> - The <code><em>allowedContent</em></code> in the code above is set to <code>true</code> to disable content filtering. - Setting this option is not obligatory, but in full page mode there is a strong chance that one may want be able to freely enter any HTML content in source mode without any limitations. - </p> </div> <form action="../../../samples/sample_posteddata.php" method="post"> <label for="editor1"> @@ -58,9 +53,19 @@ <h1 class="samples"> CKEDITOR.replace( 'editor1', { fullPage: true, - allowedContent: true, - extraPlugins: 'wysiwygarea' - }); + extraPlugins: 'wysiwygarea', + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); </script> <p>
samples/js/sample.js+26 −2 modified@@ -30,10 +30,34 @@ var initSample = ( function() { // Depending on the wysiwygarea plugin availability initialize classic or inline editor. if ( wysiwygareaAvailable ) { - CKEDITOR.replace( 'editor' ); + CKEDITOR.replace( 'editor', { + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); } else { editorElement.setAttribute( 'contenteditable', 'true' ); - CKEDITOR.inline( 'editor' ); + CKEDITOR.inline( 'editor', { + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); // TODO we can consider displaying some info box that // without wysiwygarea the classic editor may not work.
samples/old/ajax.html+15 −4 modified@@ -19,7 +19,19 @@ return; // Create a new editor inside the <div id="editor">, setting its value to html - var config = {}; + var config = { + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + }; editor = CKEDITOR.appendTo( 'editor', config, html ); } @@ -29,7 +41,7 @@ // Retrieve the editor contents. In an Ajax application, this data would be // sent to the server or used in any other way. - document.getElementById( 'editorcontents' ).innerHTML = html = editor.getData(); + document.getElementById( 'editorcontents' ).value = html = editor.getData(); document.getElementById( 'contents' ).style.display = ''; // Destroy the editor. @@ -69,8 +81,7 @@ <h1 class="samples"> Edited Contents: </p> <!-- This div will be used to display the editor contents. --> - <div id="editorcontents"> - </div> + <textarea id="editorcontents" style="width: 100%;min-height: 2em;"></textarea> </div> <div id="footer"> <hr>
samples/old/api.html+10 −0 modified@@ -166,6 +166,16 @@ <h1 class="samples"> doc.getById( 'exec-bold' ).hide(); if ( !ed.getCommand( 'link' ) ) doc.getById( 'exec-link' ).hide(); + }, + + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; } } });
samples/old/appendto.html+13 −1 modified@@ -39,7 +39,19 @@ <h1 class="samples"> // Append a CKEditor instance using the default configuration and the // provided content to the <div> element of ID "section1". CKEDITOR.appendTo( 'section1', - null, + { + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + }, '<p>This is some <strong>sample text</strong>. You are using <a href="https://ckeditor.com/">CKEditor</a>.</p>' );
samples/old/datafiltering.html+19 −49 modified@@ -13,6 +13,18 @@ <script> // Remove advanced tabs for all editors. CKEDITOR.config.removeDialogTabs = 'image:advanced;link:advanced;creatediv:advanced;editdiv:advanced'; + + CKEDITOR.on( 'instanceCreated', function( evt ) { + evt.editor.on( 'contentPreview',function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } ); + } ); </script> </head> <body> @@ -119,6 +131,13 @@ <h3>How to configure or disable ACF?</h3> <strong>allowedContent: true</strong> } ); </pre> + <p> + Please not that disabling filtering is not recommended + as <strong>it can result in XSS vulnerabilities</strong>. + It is recommended to <a + href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#use-acf-in-default-automatic-mode"> + rely on the automatic configuration</a>. + </p> <h2>Beyond data flow: Features activation</h2> <p> @@ -446,55 +465,6 @@ <h1 id="editor5" contenteditable="true"> </script> </div> - <br> - - <div> - <label for="editor7"> - Editor 7: - </label> - <div class="description"> - <p> - This editor is using a custom configuration for <abbr title="Advanced Content Filter">ACF</abbr>. - It's using the <a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_disallowed_content.html" rel="noopener noreferrer" target="_blank"> - Disallowed Content</a> property of the filter to eliminate all <code>a</code> and <code>img</code> tags, - while allowing all other tags. - </p> -<pre class="samples"> -CKEDITOR.replace( 'editor7', { - allowedContent: { - // Allow all content. - $1: { - elements: CKEDITOR.dtd, - attributes: true, - styles: true, - classes: true - } - }, - disallowedContent: 'img a' -} ); -</pre> - </div> - <textarea cols="80" id="editor7" name="editor7" rows="10"> - <h1><img alt="Saturn V carrying Apollo 11" class="right" src="assets/sample.jpg"/> Apollo 11</h1> <p><b>Apollo 11</b> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.</p> <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&nbsp;kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.</p> <h2>Broadcasting and <em>quotes</em> <a id="quotes" name="quotes"></a></h2> <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p> <blockquote><p>One small step for [a] man, one giant leap for mankind.</p></blockquote> <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p> <blockquote><p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p></blockquote> <h2>Technical details <a id="tech-details" name="tech-details"></a></h2> <table align="right" border="1" bordercolor="#ccc" cellpadding="5" cellspacing="0" style="border-collapse:collapse;margin:10px 0 10px 15px;"> <caption><strong>Mission crew</strong></caption> <thead> <tr> <th scope="col">Position</th> <th scope="col">Astronaut</th> </tr> </thead> <tbody> <tr> <td>Commander</td> <td>Neil A. Armstrong</td> </tr> <tr> <td>Command Module Pilot</td> <td>Michael Collins</td> </tr> <tr> <td>Lunar Module Pilot</td> <td>Edwin &quot;Buzz&quot; E. Aldrin, Jr.</td> </tr> </tbody> </table> <p>Launched by a <strong>Saturn V</strong> rocket from <a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center">Kennedy Space Center</a> in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of <a href="http://en.wikipedia.org/wiki/NASA" title="NASA">NASA</a>&#39;s Apollo program. The Apollo spacecraft had three parts:</p> <ol> <li><strong>Command Module</strong> with a cabin for the three astronauts which was the only part which landed back on Earth</li> <li><strong>Service Module</strong> which supported the Command Module with propulsion, electrical power, oxygen and water</li> <li><strong>Lunar Module</strong> for landing on the Moon.</li> </ol> <p>After being sent to the Moon by the Saturn V&#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the <a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis">Sea of Tranquility</a>. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the <a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean">Pacific Ocean</a> on July 24.</p> <hr/> <p style="text-align: right;"><small>Source: <a href="http://en.wikipedia.org/wiki/Apollo_11">Wikipedia.org</a></small></p> - </textarea> - <script> - - CKEDITOR.replace( 'editor7', { - allowedContent: { - // allow all content - $1: { - elements: CKEDITOR.dtd, - attributes: true, - styles: true, - classes: true - } - }, - disallowedContent: 'img a' - } ); - - </script> - </div> - <div id="footer"> <hr> <p>
samples/old/divreplace.html+12 −1 modified@@ -26,7 +26,6 @@ </style> <script> - // Uncomment the following code to test the "Timeout Loading Method". // CKEDITOR.loadFullCoreTimeout = 5; @@ -66,6 +65,18 @@ editor = CKEDITOR.replace( div ); } + + CKEDITOR.on( 'instanceCreated', function( evt ) { + evt.editor.on( 'contentPreview', function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } ); + } ); </script> </head> <body>
samples/old/inlineall.html+11 −1 modified@@ -21,6 +21,16 @@ var editor = event.editor, element = editor.element; + editor.on( 'contentPreview', function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } ); + // Customize editors for headers and tag list. // These editors don't need features like smileys, templates, iframes etc. if ( element.is( 'h1', 'h2', 'h3' ) || element.getAttribute( 'id' ) == 'taglist' ) { @@ -44,7 +54,7 @@ ]; }); } - }); + } ); </script> <link href="sample.css" rel="stylesheet">
samples/old/inlinebycode.html+13 −1 modified@@ -108,7 +108,19 @@ <h2>Technical details <a id="tech-details" name="tech-details"></a></h2> // We need to turn off the automatic editor creation first. CKEDITOR.disableAutoInline = true; - var editor = CKEDITOR.inline( 'editable' ); + var editor = CKEDITOR.inline( 'editable', { + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); </script> <div id="footer"> <hr>
samples/old/inlinetextarea.html+13 −1 modified@@ -97,7 +97,19 @@ <h2>This is a sample form with some fields</h2> </form> <script> - CKEDITOR.inline( 'article-body' ); + CKEDITOR.inline( 'article-body', { + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); </script> <div id="footer"> <hr>
samples/old/jquery.html+26 −2 modified@@ -26,8 +26,32 @@ CKEDITOR.disableAutoInline = true; $( document ).ready( function() { - $( '#editor1' ).ckeditor(); // Use CKEDITOR.replace() if element is <textarea>. - $( '#editable' ).ckeditor(); // Use CKEDITOR.inline(). + $( '#editor1' ).ckeditor( { + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); // Use CKEDITOR.replace() if element is <textarea>. + $( '#editable' ).ckeditor( { + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); // Use CKEDITOR.inline(). } ); function setValue() {
samples/old/readonly.html+12 −2 modified@@ -26,8 +26,18 @@ editor.on( 'readOnly', function() { document.getElementById( 'readOnlyOn' ).style.display = this.readOnly ? 'none' : ''; document.getElementById( 'readOnlyOff' ).style.display = this.readOnly ? '' : 'none'; - }); - }); + } ); + + editor.on( 'contentPreview', function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } ); + } ); function toggleReadOnly( isReadOnly ) { // Change the read-only state of the editor.
samples/old/replacebyclass.html+13 −0 modified@@ -8,6 +8,19 @@ <meta charset="utf-8"> <title>Replace Textareas by Class Name — CKEditor Sample</title> <script src="../../ckeditor.js"></script> + <script> + CKEDITOR.on( 'instanceCreated', function( evt ) { + evt.editor.on( 'contentPreview',function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } ); + } ); + </script> <link rel="stylesheet" href="sample.css"> <meta name="description" content="Try the latest sample of CKEditor 4 and learn more about customizing your WYSIWYG editor with endless possibilities."> </head>
samples/old/replacebycode.html+13 −1 modified@@ -39,7 +39,19 @@ <h1 class="samples"> // Replace the <textarea id="editor"> with an CKEditor // instance, using default configurations. - CKEDITOR.replace( 'editor1' ); + CKEDITOR.replace( 'editor1', { + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); </script> <p>
samples/old/tabindex.html+13 −3 modified@@ -29,15 +29,25 @@ // Apply focus class name. editor.on( 'focus', function() { editor.container.addClass( 'cke_focused' ); - }); + } ); editor.on( 'blur', function() { editor.container.removeClass( 'cke_focused' ); - }); + } ); // Put startup focus on the first editor in tab order. if ( editor.tabIndex == 1 ) editor.focus(); - }); + + editor.on( 'contentPreview', function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } ); + } ); </script> </head>
samples/old/uilanguages.html+10 −1 modified@@ -98,9 +98,18 @@ <h1 class="samples"> var languages = document.getElementById( 'languages' ); languages.value = this.langCode; languages.disabled = false; + }, + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; } } - }); + } ); } // At page startup, load the default language:
samples/old/xhtmlstyle.html+14 −2 modified@@ -212,8 +212,20 @@ <h1 class="samples"> { name: 'Cited Work', element: 'cite' }, { name: 'Inline Quotation', element: 'q' } - ] - }); + ], + + on: { + contentPreview: function( evt ) { + evt.data.dataValue = '<div style="padding: 1.5em;border: 3px #f00 solid">' + + '<h1>Content Preview was blocked</h1>' + + '<p>To ensure the highest security, the content preview in samples was blocked.</p>' + + '<p>Please refer to our ' + + '<a href="https://ckeditor.com/docs/ckeditor4/latest/guide/dev_best_practices.html#validate-preview-content">' + + 'best practices on security</a> to learn more how to properly configure and secure the content preview.</p>' + + '</div>'; + } + } + } ); </script> </p>
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-wh5w-82f3-wrxhghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-4771ghsaADVISORY
- github.com/ckeditor/ckeditor4/commit/8ed1a3c93d0ae5f49f4ecff5738ab8a2972194cbghsaWEB
- github.com/ckeditor/ckeditor4/security/advisories/GHSA-wh5w-82f3-wrxhghsaWEB
- www.incibe.es/en/incibe-cert/notices/aviso/cross-site-scripting-vulnerability-cksource-ckeditorghsaWEB
News mentions
0No linked articles in our index yet.