0

I'm developing an extension that, sometimes, will show some websites inside iframes. I've already bypassed the X-FRAME-OPTIONS issue but now I'm stuck with the simple iframe buster code, eg.:

if (top != self) {
   document.getElementsByTagName("html")[0].style.display = "none";
   top.location.replace(location);
}

I'm trying to inject javascript at the very top of the page to override the window.top object, but at document_start is already too late to inject it, ie alert() is never called before the buster script runs:

chrome.webRequest.onCompleted.addListener(function(details) {
    if (isEnabled) {
        chrome.tabs.executeScript(details.tabId, {frameId: details.frameId, runAt: "document_start", code: "alert('asas');"});
    }
}, {
    types: ["sub_frame"],
    urls: ["<all_urls>"]
});

Is there any way around this?

Thank you

Cornwell
  • 3,304
  • 7
  • 51
  • 84

1 Answers1

1

The problem is probably caused by chrome.webRequest.onCompleted.addListener listener being asynchronous

document_start injects code before any DOM is created, so that is not the cause of your problem. I have verified this while playing around and trying to answer this question.

The problem here is that chrome.webRequest.onCompleted.addListener is asynchronous, which means that when the callback (and therefor your chrome.tabs.executeScript) is executed, the browser has already started constructing the DOM.

You can start by injecting the script to all relevant iframes directly using the "content_scripts" in manifest.json instead of using programmatic injection. I haven't verified this, but you could also try injecting the script from a chrome.webRequest.onHeadersReceived listener with the "blocking" option, which allows you to handle the request synchronously. You are probably already listening to onHeadersReceived in order to remove the X-Frame-Options header anyway.


Edit:

Programmatic injection in a blocking onHeadersReceived listener is not possible. Chrome returns an error about lack of permissions - probably because the URL is not known at this point yet (the headers could cause a redirect).

Community
  • 1
  • 1
Petr Srníček
  • 2,296
  • 10
  • 22
  • Thank you. It makes sense. I'm adding the content script with the manifest now and it does get executed before the rest (even though it doesn't solve the iframe issue, but my question is answered :) ) – Cornwell Jun 03 '16 at 11:55
  • 1
    @Cornwell I stumbled [on this question](http://stackoverflow.com/q/573824/5695459) while trying to override `window.top=window.self`. I didn't succeed, but some of the answers might point you in the right direction... – Petr Srníček Jun 03 '16 at 12:15