Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting content scripts and requesting cross-origin permissions

I'm curious if the following scenario is a bug in Chrome, working as expected, or developer error.

So, I have an extension. In its manifest.json I request cross-origin permissions for two sites:

"permissions": [
    "http://www.foo.com/*",
    "http://www.bar.com/*"
]

I also declare a content script:

"content_scripts": [
    {
      "matches": ["http://www.foo.com/*"],
      "js": ["injectedScript.js"]
    }
]

So, I've indicated that I would like to inject "injectedScript.js" into all foo.com domains. "injectedScript.js" looks something like:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = handleStateChange; // Implemented elsewhere.
xhr.open("GET", 'http://www.bar.com/123'), true);
xhr.send();

Now, an iframe is added to my Chrome Extension's page. It looks like this:

<iframe src="http://www.foo.com/123"></iframe>

This frame's src matches my content script pattern. As such, when the frame loads, injectedScript.js is injected inside of it. But the XMLHttpRequest inside of injectedScript fails.

Now, this leaves me wondering what expected behavior is. It is frustrating to encounter CORS issues when I have requested the appropriate permissions... but I can also understand that I am attempting to access "http://www.bar.com/123" from an origin outside of my chrome-extension... albeit an iframe loaded into the extension which I have permission to access.

Any thoughts from anyone on the matter?

EDIT: If you're wondering what I could be getting at from a practical standpoint -- I would like to inject some javascript which can call getImageData on a video in the injected page. However, I can't, because getImageData thinks the video's src is tainted data. I've requested the appropriate permissions, but it doesn't trickle down into the iframe.

UPDATE: Here's a picture: http://i.imgur.com/PR48HO2.png

like image 956
Sean Anderson Avatar asked May 08 '13 23:05

Sean Anderson


1 Answers

The Same-Origin Policy is implemented to prevent malicious JavaScript attacks (you can read more about that here) and is an important part of the web security model. So sadly you cannot directly use an HTTP request in a content script.

However, If you happen to have access to the file you want to allow access to you can add the following PHP code to allow Cross-Origin:

header('Access-Control-Allow-Origin: *'); 

That code basically allows any website/IP address to use Cross-Origin on the following file.

If you don't have access to the file you could do a workaround such as instead of attempting to get the HTML directly, call a PHP script on a personal server that will grab it for you that has Cross-Origin enabled using the code above.

Here is an example:

header('Access-Control-Allow-Origin: *'); 

$URL = ("http://www.bar.com/123");

$HTMLfromURL = file_get_contents($URL);

echo $HTMLfromURL

And then on the Chrome Extension side have:

Note: The XMLHTTPRequest you are using is outdated and causes significant performance impacts on the user side. The code below is an asynchronous version of the same thing which does not have the negative performance impact.

var URL = "http://example.com/myscript.php";
var xhr = new XMLHttpRequest();
xhr.open("GET", URL, true);
xhr.onload = function (e) {
 if (xhr.readyState === 4) {
   if (xhr.status === 200) {
      var HTMLfromURL = xhr.responseText;
 } else {
          // Received unexpected HTML error code (such as 404, or 403)
          console.error(xhr.statusText);
        }
      }
    };
xhr.onerror = function (e) {
  console.error(xhr.statusText);
  // Run this code if failed to load page
};
xhr.send(null);
like image 127
Tidal5 Avatar answered Sep 27 '22 22:09

Tidal5