Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross Origin Chrome Extension

I have been reading and playing around with Chrome Extensions for the last week or so but I'm having trouble trying to achieve what I want. What I am trying to create is an Extension that in the background (or silently) visits a website fills out a form on the web page and retrieves the response. The website doesn't have an API and I can't create a server to do this as the website only allows X requests per IP per hour so my requests would be exhausted after a few users.

So my idea was to create a background page that would have some javascript to fill out the form using JS to getElementById, set the values, submit the form and return the response to the user seamlessly.

After testing it seems the Same Origin policy is blocking me. Here's my code:

_

manifest.json

{
  "manifest_version": 2,

  "name": "Getting started example",
  "description": "This extension shows a Google Image search result for the current page",
  "version": "1.0",

  "permissions": [
    "activeTab", "webRequest", "webRequestBlocking",
    "https://ajax.googleapis.com/"
  ],
  "background": {
      "page": "Page.html"
    }
}

Page.HTML:

<html>
    <head>
        <script src="myJS.js"></script>
    </head>
    <body>
        <iframe src="CO-TEST-FRAME.html" width="400" height="400" id="maniframe" class="maniframe"></iframe>
        <iframe src="http://www.myserver.com/iframe/CO-TEST-FRAME.html" width="400" height="400" id="maniframe2" class="maniframe2"></iframe>
        <p id="test">new</div>
    </body>
</html>

CO-TEST-FRAME.HTML:

<html>
    <head>
    </head>
    <body>
        <div id="desired" class="desired" hidden="hidden">some text</div>
    </body>
</html>

myJS.js:

window.onload = function() {
    alert("working");

    var iframe = document.getElementById("maniframe");
    var iframeStuff = iframe.contentDocument || iframe.contentWindow.document;
    var test = iframeStuff.getElementById("desired").innerHTML;

    var iframe2 = document.getElementById("maniframe2");
    var iframeStuff2 = iframe2.contentDocument || iframe.contentWindow.document;
    var test2 = iframeStuff.getElementById("desired").innerHTML;

    console.log(test);
    console.log(test2);
}

When line 9, 10, 11, 14 is commented out I get "Some Text" as expected i.e. the local frame works fine. However when I uncomment those lines the second frame (on a server) throws the following error

myJS.js:10 Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "chrome-extension://laocffdoafnoeipdndafcdbiaaephcah" from accessing a frame with origin "http://www.myserver.com".  The frame requesting access has a protocol of "chrome-extension", the frame being accessed has a protocol of "http". Protocols must match.

I understand why this is blocked (due to people being able to run JS with malicious intent) but AFAIK background pages are run in an isolated environment so all risk is mitigated anyway? Is there any way to circumvent the Same-Origin policy or do what I am trying to achieve in another way? Possibly with a content script and a 1x1 iframe on the user page?

like image 607
YengSpiz Avatar asked May 03 '16 10:05

YengSpiz


People also ask

How do I enable cross-origin in chrome?

Simply activate the add-on and perform the request. CORS or Cross-Origin Resource Sharing is blocked in modern browsers by default (in JavaScript APIs). Installing this add-on will allow you to unblock this feature.

Can chrome extensions bypass CORS?

The only solution is to add permissions to your manifest. These can be partially-regexed, for example: "permissions": [ "*://*. twitter.com/*" ], . Thankfully, there is no way for an extension to completely bypass Chrome's own CORS policy.

How do I enable cross-origin in browser?

To enable cross-origin access go to Tools->Internet Options->Security tab, click on “Custom Level” button. Find the Miscellaneous -> Access data sources across domains setting and select “Enable” option.

How do I turn off cross-origin restrictions in chrome?

In Google Chrome, you can easily disable the same-origin policy of Chrome by running Chrome with the following command: [your-path-to-chrome-installation-dir]\chrome.exe --disable-web-security --user-data-dir . Make sure that all instances of Chrome are closed before you run the command.


1 Answers

There seems to be no way to circumvent the Same-origin policy for extension pages. See https://bugs.chromium.org/p/chromium/issues/detail?id=344341.

You can achieve your objective by injecting a content script into the iframe on your background page and accessing and manipulating the iframe DOM using the content script.

A trivial example:

Add the following to your manifest.json:

"content_scripts": [
{
  "matches": ["http://www.myserver.com/iframe/CO-TEST-FRAME.html"],
  "js": ["contentScript.js"],
        "all_frames": true
}


contentScript.js:

console.log("Content script injected.");
var test = document.getElementById("desired").innerHTML;
console.log("Text from " + document.URL + ": " + test);

Note that there is no window.onload in the content script. Content scripts are injected after the DOM has loaded be default, so the window.onload event would not trigger.

In case some communcation between the background page and the content script is needed, you will need to employ message passing. There are many questions related to that on SO.

like image 77
Petr Srníček Avatar answered Sep 30 '22 11:09

Petr Srníček