0

I have written a Firefox extension that catches when a particular URL is entered and does some stuff. My main app launches Firefox with this URL. The URL contains sensitive information so I don't want it being stored in the history.

I'm concerned about the case where the extension is not installed. If its not installed and Firefox gets launched with the sensitive URL, it will get stored in history and there's nothing I can do about it. So my idea is to use a bookmarklet.

I will launch Firefox with "javascript:window.location.href='pleaseinstallthisplugin.html'; sensitiveinfo='blahblah'".

If the extension is not installed they will get redirected to a page that tells them to install it and the sensitive info won't get stored in the history. If the extension IS installed it will grab the information in the sensitiveinfo variable and do its thing.

My question is, can the bookmarklet call a method in the extension to pass the sensitive info (and if so, how) or can the extension catch when javascript is being called in the bookmarklet?

How can a bookmarklet and Firefox extension communicate?

p.s. The alternative means of getting around this situation would be for my main app to launch Firefox and communicate with the extension using sockets but I am loath to do that because I've run into too many issues over the years with users with crazy firewalls blocking socket communication. I'd like to do everything without sockets if possible.

mhenry1384
  • 7,538
  • 5
  • 55
  • 74

3 Answers3

1

As far as I know, bookmarklets can never access chrome files (extensions).

1

Bookmarklets are executed in the scope of the current document, which is almost always a content document. However, if you are passing it in via the command line, it seems to work:

/Applications/Namoroka.app/Contents/MacOS/firefox-bin javascript:alert\(Components\)

Accessing Components would throw if it was not allowed, but the alert displays the proper object.

sdwilsh
  • 4,674
  • 1
  • 22
  • 20
  • Although you can access the Components object it looks like trying to access any useful method/property on that object such as classes or QueryInterface() gets your permission denied. So I guess it's just not possible. – mhenry1384 Aug 19 '09 at 15:31
1

You could use unsafeWindow to inject a global. You can add a mere property so that your bookmarklet only needs to detect whether the global is defined or not, but you should know that, as far as I know, there is no way to prohibit sites in a non-bookmarklet context from also sniffing for this same global (since it may be a privacy concern to some that sites can detect whether they are using the extension). I have confirmed in my own add-on which injects a global in a manner similar to that below that it does work in a bookmarklet as well as regular site context.

If you register an nsIObserver, e.g., where content-document-global-created is the topic, and then unwrap the subject, you can inject your global (see this if you need to inject something more sophisticated like an object with methods).

Here is some (untested) code which should do the trick:

var observerService = Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
observerService.addObserver({observe: function (subject, topic, data) {

    var unsafeWindow = XPCNativeWrapper.unwrap(subject);
    unsafeWindow.myGlobal = true;

}}, 'content-document-global-created', false);

See this and this if you want an apparently easier way in an SDK add-on (not sure whether SDK postMessage communication would work as an alternative but with the apparently same concern that this would be exposed to non-bookmarklet contexts (i.e., regular websites) as well).

Brett Zamir
  • 14,034
  • 6
  • 54
  • 77
  • I like this post thanks for sharing Brett, but why ```content-document-global-created``` and not ```document-element-inserted``` for observe topic? – Noitidart Mar 04 '14 at 05:36
  • Ah. Can you help me understand what its doing, like what would make it better? Do you know what the subject of content-document-global-created is? What is it doing exactly? Is it setting a javascript before scripts are executed? When document-element-inserted nothing has executed yet, you can't even access dom at that point. And if you need to insert javascript why use an observer? Why not just go ```gBrowser.contentWindow.wrappedJSObject.myGlobal = true```? – Noitidart Mar 04 '14 at 06:37
  • Yes, it is also adding the variable before scripts have executed (FYI, the post has a link for "content-document-global-created", maybe obscured by the fact that I also denoted it as code). I think your `gBrowser` code will only add the global to the browser's main window instead of each individual content document's window. My code makes the variable accessible to individual web pages, including bookmarklets, observing for whenever a new one is loaded. – Brett Zamir Mar 04 '14 at 06:53
  • Because the variable is added early on, the document can check for the variable at any point in its script. The subject of `content-document-global-created` is the `nsIDOMWindow`, i.e., the individual document window which has just been observed to have loaded. – Brett Zamir Mar 04 '14 at 06:54
  • Ah I got it! Then content-document-global-created is perfect and I see you want to add it to the every page load. So why not inevery page load you do this: `subject.contentWindow.wrappedJSObject.myGlobal = true`? Also are you sure it's nsIDOMWindow, because the nsIDOMWindow would be chrome context, not the webpage right? – Noitidart Mar 04 '14 at 13:57
  • 1
    Per https://developer.mozilla.org/en/docs/Observer_Notifications#Documents it is `nsIDOMWindow` and that interface description does not seem to seem to be restricted to chrome windows. I think you are right that you do not need all that I have done (I needed the unwrapping because I was injecting an object with methods to make chrome calls) though I don't think you need the "contentWindow." part of your code snippet just `subject.wrappedJSObject.myGlobal = true`. (not sure if the wrappedJSObject is even needed for booleans, though probably yes) – Brett Zamir Mar 04 '14 at 21:36