1
votes

CKeditor in Chrome Extension popup issued: "Refused to load frame from 'about:blank' because of Content-Security-Policy."

I am trying to get a chrome extension updated to work with the manifest 2 and new Chrome API's that have currently broken the plugin with the latest version release 18.0.1025.142.

I am using CKEditor in a popup window that is issued by a background page in the extension.

But I get the Refused to load frame from 'about:blank' because of Content-Security-Policy.2 error -- is there a way to get around this?

Update

This could be related: http://code.google.com/p/chromium/issues/detail?id=77947&q=Error%20during%20tabs.executeScript%3A&colspec=ID%20Pri%20Mstone%20ReleaseBlock%20Area%20Feature%20Status%20Owner%20Summary

1

1 Answers

0
votes

In Chrome extensions, you cannot access or modify content from protocols other than file:, http:, ftp: and chrome-extension: (data:, blob: and filesystem: when the page created the resource themselves).

I considered four approaches to solve the problem:

  1. Bind a beforeload event to the document, and change the URL when it matches about:blank.
    Does not work: The CSP is activated before this event is fired.
  2. Bind a DOMNodeInserted event to the document, and check for about:blank iframes.
    Does not work: The CSP is activated before this event is fired.
  3. Use the webRequest API to intercept the request.
    Does not work: The strict match patterns do not allow the about: protocol.
  4. Change the src property before inserting the IFRAME in the document:
    1. Either manually (best option), or
    2. Modify document.createElement for IFrames, or
    3. Modify the appendChild, insertBefore and replaceChild methods for Iframes.

For all methods, you have to create a dummy page, say blank.html within your extension, and allow access via web_accessible_resources.

Manifest file example (last four lines are important):

{
  "name": "Name",
  "version": "1.0",
  "background": {"scripts": ["aboutblank.js"]},
  "manifest_version": 2,
  "content_security_policy": "default-src 'self'",
  "web_accessible_resources": ["blank.html"]
}

aboutblank.js

var BLANK_PAGE = chrome.extension.getURL("blank.html");

(function(BLANK_PAGE, createElement, appendChild, insertBefore, replaceChild) {
    HTMLDocument.prototype.createElement = function(str) {
        var elem = createElement.call(this, str);
        if (str.toUpperCase() == 'IFRAME') {
            elem.src = BLANK_PAGE;
        }
        return elem;
    };
    Element.prototype.appendChild = function(newChild) {
        iframe_check(newChild);
        return appendChild.call(this, newChild);
    };
    Element.prototype.insertBefore = function(newChild, refChild) {
        iframe_check(newChild);
        return insertBefore.call(this, newChild, refChild);
    };
    Element.prototype.replaceChild = function(newChild, refChild) {
        iframe_check(newChild);
        return replaceChild.call(this, newChild, refChild);
    };

    function iframe_check(elem) {
        if (elem instanceof HTMLIFrameElement && (elem.src == '' || elem.src.slice(0,11) == 'about:blank')) {
            elem.src = BLANK_PAGE;
        }
    }
})(BLANK_PAGE,
   HTMLDocument.prototype.createElement,
   Element.prototype.appendChild,
   Element.prototype.insertBefore,
   Element.prototype.replaceChild);

Note: Option 1 is recommended over modifying these prototype methods. Also, the prototype method does not work for <iframes> injected using .innerHTML.