0

How can I avoid the following error and why do I get it?

Edit: Maybe I have to ask how I can make objects from a privileged scope visible to a less privileged scope.

My goal is to export/return dynamically created objects to the page script as a return value of a previously cloned/injected function.

manifest.json

{
    "manifest_version": 2,
    "name": "foo",
    "version": "1.0.0",
    "description": "Does something",
    "content_scripts": [
     {
      "matches": ["<all_urls>"],
      "js": ["content-script.js"]
     }
    ]
}

content-script.js

function foo (obj) {
  obj.x = {"xxx": 444};
}
window.wrappedJSObject.foo = exportFunction(foo, window);

page script (can be insert in web console)

foo({"sss": 333})
// Error: Not allowed to define cross-origin object as property on [Object] or [Array] XrayWrapper

Deeper in the brwoser console I get this:

"ObjectActor.prototype.grip previewer function threw an exception: Error: Permission denied to access object
Stack: PseudoArray@resource://gre/modules/commonjs/toolkit/loader.js -> resource://devtools/server/actors/object.js:1797:16
ObjectActor.prototype.grip@resource://gre/modules/commonjs/toolkit/loader.js -> resource://devtools/server/actors/object.js:131:15
WCA_objectGrip@resource://gre/modules/commonjs/toolkit/loader.js -> resource://devtools/server/actors/webconsole.js:483:12
createValueGrip@resource://gre/modules/commonjs/toolkit/loader.js -> resource://devtools/server/actors/object.js:2187:14
WCA_createValueGrip@resource://gre/modules/commonjs/toolkit/loader.js -> resource://devtools/server/actors/webconsole.js:429:12
WCA_onEvaluateJS@resource://gre/modules/commonjs/toolkit/loader.js -> resource://devtools/server/actors/webconsole.js:900:21
WCA_onEvaluateJSAsync@resource://gre/modules/commonjs/toolkit/loader.js -> resource://devtools/server/actors/webconsole.js:857:20
onPacket@resource://gre/modules/commonjs/toolkit/loader.js -> resource://devtools/server/main.js:1743:15
ChildDebuggerTransport.prototype.receiveMessage@resource://gre/modules/commonjs/toolkit/loader.js -> resource://devtools/shared/transport/transport.js:761:7
Line: 0, column: 0"

I think I did not perfectly understand the XRay behaviour, so I'm not shure if this is even possible due to the scurity mechanisms.

Robbendebiene
  • 4,215
  • 3
  • 28
  • 35
  • Please [edit] the question to be on-topic: include a **complete** [mcve] that *duplicates the problem*. Including a *manifest.json*, some of the background/content/popup scripts/HTML. Questions seeking debugging help ("**why isn't this code working?**") must include: ►the desired behavior, ►a specific problem or error *and* ►the shortest code necessary to reproduce it **in the question itself**. Questions without a clear problem statement are not useful to other readers. See: "**How to create a [mcve]**", [What topics can I ask about here?](http://stackoverflow.com/help/on-topic), and [ask]. – Makyen Jan 17 '17 at 18:29
  • General: You appear to want to directly call a function in your content script from a script which you insert into the page context. You can not do this. You need to pass messages between the two contexts. This means that communication will be asynchronous. You could send a message from the page context that basically says: Please send me the results of this function with these parameters. However, if what you are wanting to do is "secretly" call the original function (in the page) from the overwritten function (in the page), you can do that. – Makyen Jan 17 '17 at 18:49
  • An [mcve] means **complete**, but *minimal*. Please give *everything* necessary to duplicate the issue. For a WebExtension, this almost always requires a *manifest.json*. Usually this will also include various other JavaScript and HTML files needed to duplicate the issue. – Makyen Jan 17 '17 at 18:54
  • The reason that a [mcve] is required is that *we want to help*. It is **much** easier to help if we don't have to recreate any of the code needed to duplicate the problem. This is code that you already have. So, please help us to help you and provide a *complete* [mcve] that duplicates the problem. Without a [mcve], the amount of effort required to even begin to help you is **much** higher, which *significantly* reduces the number of people willing/able to help you. Even if we put out the extra effort, we have to **guess** at significant portions of what your problem might be. – Makyen Jan 17 '17 at 18:55
  • It's somehow possible due to the XrayVision of an exported function, but It seems like I am not allowed to pass objects from the content script to the page script. Even though I can export objects via "cloneInto()" from the content script to the page script. – Robbendebiene Jan 17 '17 at 18:57
  • This code should be enough to reproduce it and you do not need a special manifest, just one content-script, but I will add it. – Robbendebiene Jan 17 '17 at 19:00
  • What happens when you change `obj.x` to `obj.wrappedJSObject.x`? – evilpie Jan 18 '17 at 00:30
  • when I use `obj.wrappedJSObject.x` the error is gone untill I try to access the `obj.x` or `obj` from the page script. I thought I would have to clone `{"xxx": 444} ` via `cloneInto()` but this doesn't work either. – Robbendebiene Jan 18 '17 at 11:08

1 Answers1

2

Trying to explain how Xray vision work in detail is not within my ability, but the problem here should be that you are creating {"xxx": 444} in a script context with other permission than the page script that is trying to access x. This means the page script won't be allowed to access this data. The solution is to create the object within the page context, this can be done with cloneInto.

content-script.js

function foo (obj) {
  obj.x = cloneInto({"xxx": 444}, obj);
}
window.wrappedJSObject.foo = exportFunction(foo, window);
evilpie
  • 2,718
  • 20
  • 21
  • I swear, I tried cloneInto() nearly a thousand times, but foolishly I always used the window as the targetScope... Thank you very much! – Robbendebiene Jan 18 '17 at 12:52