Inject javascript at the very top of the page \\ A

2019-09-16 06:32发布

问题:

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

回答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).