Can a firefox XPCOM component read and write page content across multiple pages?
Scenario:
A bunch of local HTML and javascript files. A "Main.html" file opens a window "pluginWindow", and creates a plugin using:
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var obj = Components.classes[cid].createInstance();
plugin = obj.QueryInterface(Components.interfaces.IPlugin);
plugin.addObserver(handleEvent);
The plugin that has 3 methods.
IPlugin.Read - Read data from plugin
IPlugin.Write - Write data to the plugin
IPlugin.addObserver - Add a callback handler for reading.
The "Main.html" then calls into the pluginWindow and tries to call the plugin method Write.
I receive an error:
Permission denied to call method UnnamedClass.Write
First, is your C++ code really a plugin or an XPCOM component, possibly installed as part of an extension? Sounds like it's the later.
If so, it's not usable from untrusted JS code - any web page or a local HTML file. It's fully usable from privileged code, the most common type of which is the extension code.
You're working around this problem when creating the component using the enablePrivilege('UniversalXPConnect') call. This is not really recommended, unless this will not be distributed to users (since this call pops a confusing box and if you set a preference to always allow file:// scripts use XPCOM, it may be a security problem, since not all local pages are trusted - think saved web pages).
Your Write call fails for the same reason - file:// pages are not trusted to use XPCOM components. You probably can get it to work if you add another enablePrivilege call in the same function as the Write call itself.
Depending on the situation, there may be a better solution.
If your files must be treated as trusted, you may want to package them as an extension and access them via a chrome:// URL. This gives the code in those pages permissions to call any XPCOM component, including yours.
If the component's methods are safe to use from any page or if the environment is controlled and no untrusted pages are loaded in the browser, you could make your component accessible to content (search for nsSidebar in mozilla code for an example and also for nsISecurityCheckedComponent).
Oh, and when you don't get good answers here, you should definitely try the mozilla newsgroups/mailing lists.
[edit in reply to a comment] Consider putting the code that needs to call the component in a chrome:// script. Alternatively, you should be able to "bless" your pages with the chrome privileges using code like this (note that it does the opposite of what you need - stripping away the chrome privileges).
Does Main.html and that other window run with chrome privileges?
If you access Main.html "normally", just putting it on the location bar of Firefox, then it will have restrictions to what it can do (Otherwise, an arbitrary web page could do exactly the same).
If you are creating a firefox plugin, place your code in a XUL overlay.
If you really want to allow any web page to do whatever it is your plugin does, you can establish some mechanism through wich the page can ask the plugin to do the operation with its chrome privileges and send the result to the page afterwards.
If you are NOT making a firefox extension...then I am afraid I misunderstood something, could you explain it more?
Related
OK so I've got this addon where I'm trying to load a bitmap from a file:/// URI and draw it to canvas.
All that goes fine until I need to get the data off the canvas using getImageData, then I run into a security exception. I go to Moz Chat and am told that because I'm loading the image from a page modded HTML File, it's a cross domain policy issue and not allowed.
The solution, they say, is to go to the main module and load the image there, copy it to a canvas, then serialize the data with getImageData and send it back to the HTML doc.
One problem: Jetpack doesn't know what "Image" is because it doesn't have an HTML DOM, thus the operation seems to be rendered more or less impossible.
Why is this a cross domain policy issue in the first place? Beyond that, how do I load the image without access to the DOM?
The simpler and best example of communication between main.js module and a content script you can read is in Add-on SDK docs: look for the section under the title Communicating With Content Scripts.
Basically, this is how the main module tells the content script (the pagemod in your case) something:
worker.port.emit("getElements", tag);
and this is how it listens to whatever the content script tells him:
worker.port.on("gotElement", function(elementContent) {
console.log(elementContent);
});
On the other side, the content script listens to what the main module says to it this way:
self.port.on("getElements", ...
And finally, a case this example is missing is how the content script may emit an event to tell something to the main module:
self.port.emit("myCustomEvent", var1=someValue, var2=otherValue, ...)
But that's the idea. I also recommend you to tale a careful look at this more general explanation about how content script (pagemods, widgets, tabs, panels, etc) work because this is the mosst important concept to understand how sdk addons work.
Last, about the cross domain issue on content scripts you can read more here.
I need a tool that can parse and insert code to the JavaScript/HTML code before the browser starts to interpret the code. I've been thinking using a proxy to do it. But now I'd like to know whether I could implement such functionality in a Firefox plug-in?
Sounds like Greasemonkey to me.
What does Greasemonkey do?
Greasemonkey lets you add JavaScript code (called "user scripts") to any web page, which will run when its HTML code has loaded. Compared to writing extensions, user scripts often offer a light-weight alternative, requiring no browser restart on user script installation nor removal, and work with the common DOM API familiar to any web developer (with somewhat elevated privileges for doing cross domain XMLHttpRequest requests and storing small portions of private data). User scripts work more or less like bookmarklets automatically invoked for any URLs matching one or more glob patterns.
http://wiki.greasespot.net/FAQ
I'm pretty sure something like TemperData might work. Or maybe Fiddler, but that's an application with additional hooks that enable it to work with Firefox.
TemperData: https://addons.mozilla.org/en-US/firefox/addon/966/
Fiddler: http://www.fiddler2.com/fiddler2/
Of course both work on a network level, so they may be a bit more arcane than what you'd need.
I am loading content from another page and depending on the content of page, changing content of my page and this is giving me cross site scripting issues.
When i use iframe, since the content is from other domain, content of iframe becomes inaccessible.
When i use ajax and try to inject the content as plain html code, XmlHttpRequest object throws permission denied exception due to cross site scripting.
When i use JSONP, such as getJSON in JQuery, it only supports GET protocol and it is not adequate for further processing.
I wonder what other options i can try. Heard that DOJO, GWT,Adobe Air do some XSS, but dont know which one is the best.
Thanks,
Ebe.
Without JSON-P, your only option is to run a proxy script on your own server that fetches the content from the external site and pipes it back to the browser.
The browser fetches the content from the script on your server, hence no cross-domain issues, but the script on your server dynamically fetches it from the external site.
There's an example of such a script in PHP here: http://www.daniweb.com/code/snippet494.html (NB. I haven't personally used it).
If you have control over both domains, take a look at EasyXDM. It's a library which wraps cross-browser quirks and provides an easy-to-use API for communicating in client script between different domains using the best available mechanism for that browser (e.g. postMessage if available, other mechanisms if not).
Caveat: you need to have control over both domains in order to make it work (where "control" means you can place static files on both of them). But you don't need any server-side code changes.
To add to what RichieHindle says, there are some good script (Python+Cron) that you can plonk on your server and it will check for changes to a POST/GET location and cache the changes on your server.
Either set your triggers low (once every 10 mins/ 1 per day) or you might get blacklisted from the target.
This way, a local cache won't incur the HTTP overhead on every AJAX call from the client.
I need to create a portable script to give to others to implement on their websites that will dynamically show content from my database (MySQL).
I know AJAX has a cross-site problem, but it seems that Google's ad's somehow manage the effect in a cross-browser / cross-site fashion.
Knowing that I have to give people a simple cut/paste snippet to put in their website...how can I achieve this? How did Google?
They use an <iframe>, so the ad is served from their server, and can talk to their database. I'm not actually sure that they use any sort of AJAX from their ads, though; they appear to just be mostly static content, with a few scripts for tweaking the formatting (which are optional, since they want their ads to be visible even if users have JS turned off).
Remember, you can always look into this on your own, and see what they did. On Firefox, use Firebug to explore the html, css, and scripts on a site. On WebKit based browsers (Safari, Chrome, and others), you can use the Web Inspector.
Google's ad code is loaded via a script tag that calls a remote javascript file. The AJAX restrictions that are generally enforced with xmlhttp, iframe, and similar AJAX requests don't apply when it comes to loading remote javascript files.
Once you've loaded the javascript file, you can create iframes in your page that link back to the actual hosted content on your server (and feed them any data about the current page that you wish).
jQuery has built in support for jsonp in their ajax calls. You may want to lookin in to using that if you are really needing to use ajax.
http://api.jquery.com/
http://docs.jquery.com/Ajax
You don't need iFrames and you don't need AJAX. It's really, really simple!
You pull in a remote JS file that is actually a constructed file from php/asp/whatever. In your JS file you have a document.write script that writes the content. It's that simple.
We do this all the time with media stored on separate sites. Here's an example.
YOUR SERVER: file.php (which outputs js)
<script>
document.write("I'm on a remote server");
</script>
OTHER SITE:
<script src='http://www.yourserver.com/file.php'></script>
And it will output the content generated by the script. To make the content customized you can put in script vars above the script call that will adjust what your file pulls out. From there it's pretty straightforward.
I realize this question is a year old, but I've written a library that can help with the document.write part of the problem (whether this is a TOS violation, I don't know) writeCapture.js. It's pretty simple:
$('#ads').writeCapture().html('<script src="whatever-your-adsense-code-is"> </script>');
The example uses jQuery, but you can use it standalone as well.
Right now i'm building a firefox plugin that duplicates some functionality on my website. It takes in an email address and then returns information to the user. The easiest way to do this in the plugin is to use an Iframe and render that super simple form on my website. All of this works great, but to make the plugin really useful, i would like the plugin to have access to the information that the iframe renders, so it can use it in the current window that the user is in.
Is it possible to pass information back through an Iframe in this manner? I know there are quite a few domain access restrictions with Iframes, so any help or insight is appreciated!!
I've done this two ways.
If the iframe is on the same domain as the parent website, you can just, in javascript, access window.parent.
If it isn't, however...I've done a dirty trick. I'll share it here, though, as it may help.
We created a page on the other domain, which would call to window.parent.parent. We put that in a hidden iframe inside the iframed page, and send it a querystring argument or two. It's not pretty, but it gets around cross-domain scripting problems.
This basically means that you have this sort of thing:
admin.example.com
content.example.com - iframe
admin.example.com?contentid=350 - hidden iframe that makes a window.parent.parent call.
Is the point of this whole exercise functional testing of your website? If so, instead of your custom Firefox plugin, consider using Selenium to automate interactions with websites. It works with all major browsers and supports the inspection of page elements you are trying to do (using XPath). It also features a Firefox plugin called Selenium IDE that allows you to conveniently "record" your interactions with a website for automated playback later.