10

In the context of a user script, for example executed by Tampermonkey, is it possible to communicate between two pages of different domains, which set 'X-Frame-Options' to 'SAMEORIGIN'?

I know about this way of sending messages from one page to another by using iFrames and postMessage, but when working with sites you dont control, like in my case Stack Overflow and Google (working on a bot to automate something for myself), you'll get the SAMEORIGIN error when trying to create the iFrame.

But I thought since I'm able to insert script in both pages, it might be possible to pull off some workaround or alternate solution.

One suggestion, a shared worker looked promising, but it seems to require the page to be from the same origin. Also I looked at the Broadcast Channel API spec, but it isn't implemented anywhere yet, and it also seems to be bound to the same origin policy.

Another suggested possibility mentioned so far in the comments is to use the GM API since this is a user-script (extended / special JS features). With GM_xmlhttpRequest we can ignore cross domain restrictions and load google.com, then put it in an iframe, but all the sources will point to the site where the iframe is embedded, so searching the Google page tries to execute the search params on the parent site's domain.

GM_xmlhttpRequest({
    method: "GET",
    url: "https://www.google.com",
    headers: {
        "User-Agent": "Mozilla/5.0",
        "Accept": "text/xml"
    },
    onload: function(response) {
        $('html').html('<iframe id="iframe"></iframe>');
        $("#iframe").contents().find('html').html(response.responseText);
});

Maybe I could edit the search requests to point to google.com specifically, rather than letting the search adopt the parent page's domain. And if that fails due to some hangup with the same origin policy, I could even try to replace Google's xmlhttpRequest's with GM_xmlhttpRequest's, but I'm not sure if that can be done since the user script, if you load GM functions, will run in a sandbox, unable to intertwine with the pages scripts if I understand correctly. I'm just not sure.

On the other hand, if we can trick the iframe's contents to treat google.com as the domain for requests, though we're in business, but examples don't seem to exist for this kind of thing, so I'm having trouble figuring out how to make it happen.

Community
  • 1
  • 1
  • 1
    Same origin prevent browser from loading page. There is no place to insert your script – Alexey Ten Aug 01 '16 at 04:31
  • 2
    There's always the `GM_*` functions. I believe Tampermonkey supports the ones you would need. – Alexander O'Mara Aug 01 '16 at 04:33
  • 1
    _"But I thought since I'm able to insert script in both pages"_ If you are able to insert ` – guest271314 Aug 01 '16 at 04:35
  • @AlexeyTen They are talking about user-scripts: https://wiki.greasespot.net/User_script – Alexander O'Mara Aug 01 '16 at 04:35
  • @AlexanderO'Mara I know, but user scripts still need document to be loaded – Alexey Ten Aug 01 '16 at 04:40
  • @AlexanderO'Mara see my updates regarding the GM functions. Thanks for the tip by the way, we might be onto something with that. –  Aug 04 '16 at 04:48
  • 1
    Don't worry about the sandbox. First, you're always running in a sandbox. Second, it's mostly there to provide a consistent environment for you (also to expose you the gm_ functions without giving them to the page, I guess). Third, you have access to `unsafeWindow`, which is the page's own global scope, from which you can access almost everything you want - and if you put stuff there, the page will have access to it. – John Dvorak Aug 04 '16 at 06:48
  • _"is it possible to communicate between two pages of different domains"_ Not certain what you are trying to achieve? What data are you trying to communicate between two domains? – guest271314 Aug 08 '16 at 00:26

1 Answers1

2

Yes, it is possible, via 2 routes:

  1. Since it's a user-script, you have access to special functions known as GM functions. With GM_xmlhttpRequest, we can send a request which ignores the same origin policy, allowing us to load the third party page in an iFrame, allowing communication between the frames via postMessage. The good thing about this is there's no page reloading, but the bad thing is, you will have to dynamically modify the frame's native xmlhttpRequest to execute a GM_xmlhttpRequest and specify the full target URL, not just a path such as /example.js, otherwise the domain of the outer window will be used in any requests made by the internal frame.
  2. We can use URL queries by openning a tab of the same origin as the page you want to communicate with. Then we can use shared web workers to post messages to any previously opened pages of that domain and send the data from the URL query to the page you want. The pros are you don't have to dynamically modify the pages' scripts, but the cons are that you have to open a new tab for each message between different domains.