c00000fd
c00000fd

Reputation: 22255

XSS "Blocked a frame with origin from accessing a cross-origin frame" error in content script for a Chrome extension

I've had this extension in the Google Chrome store for a while now. After doing a maintenance update I noticed that the following line from the content.js (content script):

//Get top document URL (that is the same for all IFRAMEs)
var strTopURL = window.top.document.URL;

is now throwing the following exception when the loaded page has an IFRAME in it:

Blocked a frame with origin "https://www.youtube.com" from accessing a cross-origin frame.

Like I said, it used to be the way to obtain the top document URL for your extension (from the content script). So what's the accepted way to do it now?

PS. Again, I'm talking about a Google Chrome extension (and not just a regular JS on the page.)

EDIT: This script is running under the content_scripts in the manifest.json that is defined as such:

"content_scripts": [
    {
        "run_at": "document_end",
        "all_frames" : true,
        "match_about_blank": true,
        "matches": ["http://*/*", "https://*/*"],
        "js": ["content.js"]
    }
],

Upvotes: 0

Views: 1020

Answers (1)

woxxom
woxxom

Reputation: 73506

The content script should ask your background script to do it via messaging:

chrome.runtime.sendMessage('getTopUrl', url => {
  // use the URL here inside the callback or store in a global variable
  // to use in another event callback that will be triggered in the future
  console.log(url);
});
// can't use it right here - because the callback runs asynchronously

The background script should be declared in manifest.json:

"background": {
  "scripts": ["background.js"],
  "persistent": false
},

You'll also need need specific URL permissions in manifest.json or allow all URLs:

"permissions": ["<all_urls>"]

And the listener in the background script:

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg === 'getTopUrl') {
    chrome.tabs.get(sender.tab.id, tab => sendResponse(tab.url));
    // keep the message channel open for the asynchronous callback above
    return true;
  }
});

Upvotes: 1

Related Questions