If you want to learn more about how to detect extensions on Firefox and Chrome, read this paper describing the methodology or visit the amazing Inria site above, but here we will try to achieve the same on Microsoft Edge.

Installing an Extension

In the extensions store I randomly selected the AdGuard blocker. After two clicks it was installed and automatically opened a thank-you page that gave me ideas before even starting the research. Check it out.

That URL is all we need to get started. If we can load it in an iframe and detect its presence (onload/onreadystatechange/whatever) to distinguish it between a default Edge 404 page, we are almost done. But unfortunately iframes refuse to load the ms-browser-extension: protocol.

// returns null when the URL is ms-browser-extension: (not useful for us)

It opens! But, it is not really useful for us because the window.open() returns null instead of a window object, with or without the installed extension. In other words, when we try to open a new window using the extension-protocol ms-browser-extension: it will always return null. So even if we can actually open the window (which by the way is an ugly solution), we have no way to check if the content was loaded.

What about images from the extensions? Maybe images are exposed to the main page and using the onload/onerror events we can detect if the extension is installed. Let’s first find out where the extension files are located in our file-system.

Locating the Extension Files

Fire up Process Monitor and include MicrosoftEdgeCP.exe in the filters. Close Edge and load the thank-you page from AdGuard by simply pasting the URL into Edge address bar. Bang! We can immediately see in Process Monitor where the files are located. Remember, our goal is to find an image from this extension to see if we can load it and detect its presence via onload/onerror.

This does not impress me, at all. We are essentially doing nothing new and just like the other detection methods (for Chrome/FF), we depend on the extension cooperation to allow resources to be loaded. If there is an extension that does not have the web accessible resources in the manifest, how will we detect it?

A Generic Way to Detect Extensions

Update 2017-04-11: the following technique crashes badly after Windows Creators Update, however, there are at least two variations that work. One of them will be posted soon. Thanks for your patience!

After playing around a few minutes with different tricks and trying to load non-accessible-resources, I decided to try something similar to Soroush’sIE DTD trick. which tries to load a resource using the Microsoft XMLDOM object, and depending on the error number it will know if the file was present or not. On Edge we don’t have the XMLDOM object but we can do something similar with the regular XMLHttpRequest.

If try to open a resource and the extension exists it throws an access denied, otherwise an unspecified error. In fact, to honour Soroush amazing finding we will try to be as elegant as him and use the error number received in the catch. A block of code is worth a thousand words. Take a look below:

Now this is looking good, thanks Soroush for all your brilliant ideas!

By the way, have you noted that the URL that we are using is not even pointing to a specific resource? The xml trick works against the directory name and it does not even need to point to a specific resource of the extension, so now, having the extension ID is enough to detect it. If we want to build a generic tester to find all installed extensions like the one that we’ve seen for Chrome and Firefox, we need to first install all the extensions in our Edge and take note of their IDs. It’s easy, just install the extension, load a blank page and press F12. That enough to reveal the extension ID. I’ve installed a few of them so it becomes clearer in the screenshot below.

With those names we can now create a generic extension detector for Microsoft Edge. Only disabled extensions won’t be loaded in Developer Tools but we can still find them in the registry: