wh0
wh0

Reputation: 510

How to waive Xrays vision in latest Firefox WebExtension?

I am following the guide here:

I want to waive Xrays vision of an iframe:

var foo = $(Components.utils.waiveXrays($("#foobar").get(0).contentWindow.document));

The above is running in a content script with manifest.json like the following:

  "content_scripts": [
    {
      "matches": /* something */,
      "css": ["content.css"],
      "js": ["jquery-3.2.1.js","content.js"]
    }
  ]

But I will get an undefined object error:

[firefox/index.js][debug] Firefox stderr: JavaScript error: , line 0: Error: Components.utils is undefined

I think the guide on Mozilla website is outdated. It is not for pure WebExtension implementation.

What should be the correct latest method now?

Upvotes: 0

Views: 377

Answers (2)

wh0
wh0

Reputation: 510

After a couple of days of research (and asking in mozilla firefox mailing list). I already found out the solution. The correct guide is here (as of 2017 May 14):

In the SDK, content scripts can share objects with page scripts, using techniques like unsafeWindow and createObjectIn. In WebExtensions, the unsafeWindow is available via wrappedJSObject instead. All the export helper functions are available, too.

If I want to access the waived xrays version of window object, I should use:

window.wrappedJSObject

If there is an iframe within the page and I want to access the object inside it. Here is one of the way:

document.getElementById("the_iframe").contentWindow.wrappedJSObject

However, I found that if the iframe is in cross-domain, the wrappedJSObject will be not accessible (as of Firefox version 51.0.1). I need to seek another method as follow:

Provide a content script that inject all child iframe and then implement a background script that provide a messaging bridge between the child iframe and the top page:

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

  "content_scripts": [
    {
      "matches": ["*://*.something"],
      "css": ["content.css"],
      "all_frames": true, /* ADD THIS LINE */
      "js": ["jquery-3.2.1.js","content.js"]
    }
  ]

In content.js, do something like that:

if(window.top == window.self) { // main
  main();
}
else if(window.name == "frameA") { // match frameA
  browser.runtime.onMessage.addListener(function(msg) {
    /* Check the message msg and then access the waived X rays vision by window.wrappedJSObject */
     if(msg matches something) {
       var ret = window.wrappedJSObject.foobar(msg.data);
       /* Send back the return value to background.js by browser.runtime.sendMessage */
       browser.runtime.sendMessage({"returnVal": ret, "from": "frameA"}); 
     }
    }
  });
}

In background.js, do some message forwarding:

function forward_to_all(r)
{
  var forwardMessage = function(tabs) {
    for(let tab of tabs) {
      browser.tabs.sendMessage(tab.id,r);
    }
  }
  browser.tabs.query({currentWindow:true, active:true}).then(forwardMessage);
}
browser.runtime.onMessage.addListener(function(msg) {
  if(msg matches something) {
    forward_to_all(msg);
  }
});

Upvotes: 3

erikvold
erikvold

Reputation: 16508

You aren't meant to be able to waive xrays in firefox webextensions, if you are able to then it's a bug that would quickly be disabled.

I think the guide on Mozilla website is outdated.

Indeed.

What should be the correct latest method now?

what you want to do (ie waive xray wrappers) is not possible. Probably best to think about a new way to achieve what you want, whatever that is (I can't tell by the description).

Upvotes: 0

Related Questions