Details
-
Bug
-
Resolution: Fixed
-
Major
-
1.10
-
None
-
None
Description
The popular Greasemonkey browser extension in FIrefox can inject <script> elements into the <body> of the CKEditor's IFRAME. These <script> elements' contents then get erroneously transformed into HTML-encoded markup that gets saved into the wiki page content.
I was able to repro on Firefox/Greasemonkey using the following fabricated script:
// ==UserScript== // @name Example of Interfering With XWiki CKEditor // @namespace http://tampermonkey.net/ // @version 0.1 // @description example of interfering with XWiki CKEditor // @author You // @include * // @grant none // ==/UserScript== (function() { 'use strict'; function injectFunctionIntoPage(f) { var script = document.createElement('script'); script.appendChild(document.createTextNode(f)); document.body.appendChild(script); } injectFunctionIntoPage('(function(){console.log("injected");})();'); })();
Repro:
1. Install Greasemonkey for Firefox and add the above userscript to it.
2. Open any XWiki CKEditor page.
3. Switch to Source edit mode.
4. Observe that part of the GM script gets injected as content into the editor.
The same issue occurs if you just "Save" instead of switching to Source edit mode at step 3 above.
Note that this issue does NOT repro on TamperMonkey/Chrome, evidently because GM runs in the context of each IFRAME on the page whereas TM only runs in the root <body>.
My understanding is that it's not possible for a webpage to detect whether Greasemonkey is running – and this is by design.
However, one possible reasonable fix may be to strip out any <script> elements present in the CKEditor WYSIWYG IFRAME before saving or going to Source view.
This approach should work since a user would not normally be able to add an unencoded <script> tag to the WYSIWYG editor, and even in CKEditor's Source edit mode, typing in e.g. "<script>alert(1);</script>" gets transformed into "<script>alert(1);</script>" when you switch back to WYSIWYG mode.
And in the case where you write something like
{{html}}<script>alert(1);</script>{{/html}}
in Source edit mode, that gets transformed into
<!--{cke_protected}%3Cscript%3E%2F%2F%3C!%5BCDATA%5B%0Aalert(1)%3B%0A%2F%2F%5D%5D%3E%3C%2Fscript%3E-->
... so again, this is distinct from Greasemonkey's injection of unescaped <script> elements, and thus we should still be able to safely strip out unescaped <script> elements to handle this scenario.
This would not mitigate the potential for other kinds of HTML elements to be injected into the IFRAME body, but in the case of Greasemonkey scripts, the injection of <script> tags are by far the most common scenario, so this proposed fix seems like an appropriate solution for the specific issue outlined above.