Search code examples
javascriptgoogle-chrome-extensionsame-origin-policy

Avoid cross-origin policy via Chrome extension


Site A is a website with an <iframe> containing Site B. This is running on a chrome browser with an extension.

I have control over the extension. What I would like to do is give the user controls to edit parts of Site B.

The following is invoked when a user presses a button on the extension. The intention is to load jQuery in so I can use it, target the iframe on the page, reach into the iframe then change its body color.

chrome.tabs.executeScript(null, {file: 'assets/jquery.min.js'}, function () {
  chrome.tabs.executeScript({
    code: "jQuery('iframe').contents().find('body').css('backgroundColor', 'red');"
  });
});

Site A and Site B are on different domains, so the same origin policy kicks in. It's also worth noting that Site B has not given cross origin access rights to Site A. I also am not the owner of Site A or Site B so cannot amend their cross origin policies.

My hope is that when running from the extension I have a little more consent from the user to be able to get around the same origin policy and perform the action above.


Solution

  • If you want your script to be injected into the frame you can use the allFrames option to inject the code in all the frames of the page.

    Before running the code you'll have to check if you are inside A or B: you can do this by comparing window.self with window.parent. In the top frame (A) those will be the same object, but inside an <iframe> (like B) those will be different.

    Here it is:

    chrome.tabs.executeScript(null, {file: 'assets/jquery.min.js', allFrames: true}, function () {
        chrome.tabs.executeScript({
            code: "if (self != parent) jQuery('body').css('backgroundColor', 'red');",
            allFrames: true
        });
    });
    

    NOTE: since January 2021, for Manivest V3 use chrome.scripting.executeScript() instead.

    The above code will be injected both into A and B, but will execute only in B. If multiple frames are in A, you'll also have to check if the frame is correct using for example window.location.hostname.