From c40eeff50f24d5cb595a3119183f61f597de7a22 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 26 Jun 2020 14:40:23 -0400 Subject: [PATCH] override some CKEditor internals to invalide inline event handlers --- www/pad/csp.js | 8 ++++---- www/pad/inner.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/www/pad/csp.js b/www/pad/csp.js index 7c1a2ac9e..2e0d7a4ef 100644 --- a/www/pad/csp.js +++ b/www/pad/csp.js @@ -14,11 +14,11 @@ define(['jquery'], function ($) { var $a = $('.cke_toolbox_main').find('.cke_button, .cke_combo_button'); $a.each(function (i, el) { var $el = $(el); - $el.on('keydown blur focus click', function (e) { + $el.on('keydown blur focus click dragstart', function (e) { e.preventDefault(); - var attr = $(el).attr('on'+e.type); + var attr = $(el).attr('oon'+e.type); if (!attr) { return; } - if (e.type === "blur") { return false; } + if (['blur', 'dragstart'].indexOf(e.type) !== -1) { return false; } var reg = /CKEDITOR.tools.callFunction\(([0-9]+),(this|event)\);return false;/; var m = attr.match(reg); if (!m) { return; } @@ -88,7 +88,7 @@ define(['jquery'], function ($) { }).contents().find('body').on('click dragstart mouseover mouseout', '.cke_button, a.cke_colormore, a.cke_colorbox, .cke_colorauto, .cke_combo_button, .cke_panel_listItem a, a.cke_menubutton', function (e) { e.preventDefault(); if (e.type === 'dragstart') { return false; } - var attr = $(e.currentTarget).attr('on'+e.type); + var attr = $(e.currentTarget).attr('oon'+e.type); if (!attr) { return; } var reg = /CKEDITOR.tools.callFunction\(([0-9]+),'?([A-Za-z0-9 ?]+)'?(,'([A-Za-z0-9 ]+)')?\);/; var match = attr.match(reg); diff --git a/www/pad/inner.js b/www/pad/inner.js index 6022586e4..5a97019c6 100644 --- a/www/pad/inner.js +++ b/www/pad/inner.js @@ -980,6 +980,36 @@ define([ Ckeditor.plugins.addExternal('blockbase64', '/pad/', 'disable-base64.js'); Ckeditor.plugins.addExternal('comments', '/pad/', 'comment.js'); Ckeditor.plugins.addExternal('wordcount', '/pad/wordcount/', 'plugin.js'); + +/* CKEditor4 is, by default, incompatible with strong CSP settings due to the + way it loads a variety of resources and event handlers by injecting HTML + via the innerHTML API. + + In most cases those handlers just call a function with an id, so there's no + strong case for why it should be done this way except that lots of code depends + on this behaviour. These handlers all stop working when we enable our default CSP, + but fortunately the code is simple enough that we can use regex to grab the id + from the inline code and call the relevant function directly, preserving the + intended behaviour while preventing malicious code injection. + + Unfortunately, as long as the original code is still present the console + fills up with CSP warnings saying that inline scripts were blocked. + The code below overrides CKEditor's default `setHtml` method to include + a string.replace call which will rewrite various inline event handlers from + onevent to oonevent.. rendering them invalid as scripts and preventing + some needless noise from showing up in the console. + + YAY! +*/ + CKEDITOR.dom.element.prototype.setHtml = function(a){ + if (/callFunction/.test(a)) { + a = a.replace(/on(mousedown|blur|keydown|focus|click|dragstart)/g, function (value) { + return 'o' + value; + }); + } + return this.$.innerHTML=a; + }; + module.ckeditor = editor = Ckeditor.replace('editor1', { customConfig: '/customize/ckeditor-config.js', });