The Old Technique
Detecting which Chrome extensions are installed has always been a trivial matter of finding a specific extension ID and trying to load the manifest.json file, which is always located in the same spot:
Denying load of chrome-extension://abcdefghijklmnopqrstuvwxyz012345/manifest.json. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.
What happened to the good old detection code that used to work seamlessly? And what is the web_accessible_resources manifest key?
Manifest Version 2
In Chrome 18, manifest version 1 was deprecated. Google is slowly decreasing its support, finally making it unavailable to developers in September 2013. In the new version, Google introduced several changes to the manifest file and one of them is breaking most of the existing detection code.
The web_accessible_resources array was introduced to allow developers to choose exactly which resources can be reached by external sources. If a local resource isn't included in the array, then a remote web page won't be able to load it. The array looks like the following example:
"web_accessible_resources": [ "logo.png", "menu.html", "style.css" ]
In order to determine the manifest version, the manifest.json file must be checked properly. The "manifest_version" parameter is self-explanatory and determines if the JSON has been updated to the latest version. If the manifest is already in the latest version ("manifest_version": 2), then the file includes the web_accessible_resources array.
First of all, check the web_accessible_resources array and determine the resources that can be loaded. If the array is not empty, choose a resource of your choice, knowing that its location is chrome-extension://[EXTENSION ID]/[RESOURCE PATH].
var testScript = document.createElement("script");
testScript.setAttribute("onload", "alert('Extension Installed!')");
testScript.setAttribute("src", "chrome-extension://[EXTENSION ID]/[RESOURCE PATH]");
The previous code should work for every type of file, whether it's a text file (eg. json, html, script) or a picture.
The new implementation of the Chrome extension manifest provides developers with an easy way to whitelist resources loaded from external sources. Any code developed in order to detect installed add-ons won't be affected, as long as extensions keep allowing at least one local resource in the web_accessible_resources array.
Giovanni Cattani works as a security specialist and likes to mess around with applications of all kinds. He occasionally contributes to BeEF and writes about stuff he likes at gcattani.co.vu