Check Whether User Has a Chrome Extension Installed

Check whether user has a Chrome extension installed

I am sure there is a direct way (calling functions on your extension directly, or by using the JS classes for extensions), but an indirect method (until something better comes along):

Have your Chrome extension look for a specific DIV or other element on your page, with a very specific ID.

For example:

<div id="ExtensionCheck_JamesEggersAwesomeExtension"></div>

Do a getElementById and set the innerHTML to the version number of your extension or something. You can then read the contents of that client-side.

Again though, you should use a direct method if there is one available.


EDIT: Direct method found!!

Use the connection methods found here: https://developer.chrome.com/extensions/extension#global-events

Untested, but you should be able to do...

var myPort=chrome.extension.connect('yourextensionid_qwerqweroijwefoijwef', some_object_to_send_on_connect);

Check if user has a third party Chrome extension installed

Assuming you need it from a website

connect/message method implies that the extension specifically listed your website in the list of origins it expects connection from. This is unlikely unless you wrote this extension yourself, as this cannot be a wildcard domain.

Referring to files within the extension from web context will return 404 simulate a network error unless the extension declared them as web-accessible. This used to work before 2012, but Google closed that as a fingerprinting method - now extensions have to explicitly list resources that can be accessed. The extension you specifically mention doesn't list any files as web-accessible, so this route is closed as well.

chrome.management is an extension API; websites cannot use it at all.

Lastly, if an extension has a content script that somehow modifies the DOM of your webpage, you may detect those changes. But it's not very reliable, as content scripts can change their logic. Again, in your specific case the extension listens to a DOM event, but does not anyhow make clear the event is received - so this route is closed.

Note that, in general, you cannot determine that content script code runs alongside yours, as it runs in an isolated context.

All in all, there is no magic solution to that problem. The extension has to cooperate to be discoverable, and you cannot bypass that.

Assuming you need it from another extension

Origins whitelisted for connect/message method default to all extensions; however, for this to work the target extension needs to listen to onConnectExternal or onMessageExternal event, which is not common.

Web-accessible resources have the same restrictions for access from other extensions, so the situation is not better.

Observing a page for changes with your own content script is possible, but again there may be no observable ones and you cannot rely on those changes being always the same.

Similar to extension-webpage interaction, content scripts from different extensions run in isolated context, so it's not possible to directly "catch"code being run.

chrome.management API from an extension is the only surefire way to detect a 3rd party extension being installed, but note that it requires "management" permission with its scary warnings.

Detect if a Chrome extension is installed by users

Define your id at the start of your background.js like so: var id = chrome.runtime.id;.

Also you need to add your site to the externally_connectable instead of the permissions in the manifest.json as:

"externally_connectable": {
"matches": ["https://*.mydomain.com/*"]
}

Checking if user has a certain extension installed

To detect if an extension is installed in Chrome, you can check for a known resource included in the extension such as an image. Resources for the extension are referenced using the following URL pattern:

chrome-extension://<extensionID>/<pathToFile>

The basic detection technique involves creating a hidden image tag and attaching load and error events to it to see if the image loads (as described here for Firefox):

extensionImg.setAttribute("src", "chrome-extension://<INSERT EXTENSION ID HERE>/images/someImage.png"); // See below for discussion of how to find this

/*
* Add event listeners for both "load"- and "error"-event
* Set the variable showing the existence of the extension by
* setting it to "true" or "false" according to the fired event
*/
extensionImg.addEventListener("load", function(e) {
extensionExists = true;
removeImgTag(e);
}, false);
extensionImg.addEventListener("error", function(e) {
extensionExists = false;
removeImgTag(e);
}, false);

function removeImgTag(e) {
e.currentTarget.parentNode.removeChild(e.currentTarget);
}

Check the installation directory of the extension in the Chrome configuration to find a likely target for detection. On my Linux workstation extensions are located in:

 ~/.config/chromium/Default/Extensions

You can see that I have 3 extensions installed right now:

~/.config/chromium/Default/Extensions$ ls
cpecbmjeidppdiampimghndkikcmoadk nmpeeekfhbmikbdhlpjbfmnpgcbeggic
cpngackimfmofbokmjmljamhdncknpmg

The odd looking names are the unique IDs given to the extension when it is uploaded to the Chrome webstore. You can obtain the ID either from the webstore or by going to the Extensions tab (wrench -> Extensions) and hovering over the link to the extension in question, or "Screen Capture (by Google)" in this case (note the asterisked extension ID):

https://chrome.google.com/webstore/detail/**cpngackimfmofbokmjmljamhdncknpmg**

In the extension directory there will be one or more versions; you can ignore this. Within the version directory is the actual content of the extension:

~/.config/chromium/Default/Extensions/cpngackimfmofbokmjmljamhdncknpmg/5.0.3_0$ ls
account.js images page.js sina_microblog.js
ajax.js isLoad.js picasa.js site.js
background.html _locales plugin style.css
editor.js manifest.json popup.html ui.js
facebook.js notification.html sha1.js upload_ui.js
hotkey_storage.js oauth.js shortcut.js
hub.html options.html showimage.css
i18n_styles page_context.js showimage.html

In the case of the Screen Capture extension there are a number of images to use:

~/.config/chromium/Default/Extensions/cpngackimfmofbokmjmljamhdncknpmg/5.0.3_0/images$ ls
arrow.png icon_128.png icon_save.png print.png
copy.png icon_16.png line.png region.png
cross.png icon_19.png loading.gif screen.png
custom.png icon_32.png loading_icon.gif sina_icon.png
delete_account_icon.png icon_48.png mark.png toolbar_bg.png
down_arrow.png icon_close.png picasa_icon.png upload.png
facebook_icon.png icon_copy.png popup_bg.jpg whole.png

These can be referenced under this URL:

chrome-extension://cpngackimfmofbokmjmljamhdncknpmg/images/arrow.png

This technique obviously depends on the stability of the content of the extension. I recommend using an image that looks likely to remain through all versions.


As mentioned above, the same technique can be used to detect Firefox extensions. In this case the content URL looks like this:

chrome://<EXTENSION NAME>/content/<PATH TO RESOURCE>

On my Linux workstation Firefox extensions are located in:

 ~/.mozilla/firefox/<USER PROFILE ID>/extensions

Where <USER PROFILE ID> looks something like this: "h4aqaewq.default"

You can see that I have 2 extensions installed right now, one of which is a directory installation and the other of which is a XPI (pronounced "zippy") file:

~/.mozilla/firefox/h4aqaewq.default/extensions$ ls
{3e9a3920-1b27-11da-8cd6-0800200c9a66} staged
firebug@software.joehewitt.com.xpi

The "staged" directory is where Firefox keeps extensions that will be updated (I think). The GUID directory with the brackets is a directory-based extension installation, and the .xpi file is Firebug.

Note: XPI is going away (see the link above). It's basically a zip file that can be opened and inspected by anything that understands zip. I used Emacs.

Finding the extension ID in Firefox is a bit more involved. Go to "Tools -> Add-ons", click the Extensions tab, click the "More" link next to the extension description, then click the "reviews" link to go to the Firefox extension site and get the ID from the URL (note the asterisked extension ID):

https://addons.mozilla.org/en-US/firefox/addon/**firebug**/reviews/?src=api

There's probably an easier way to do this; suggestions welcome.

TODO: how to find a likely image in a Firefox extension.


As an extra note, in Chrome you can only communicate with an extension via the shared DOM of the page: Host page communication



Related Topics



Leave a reply



Submit