Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect web extensions #106

Closed
abrahamjuliot opened this issue Jan 6, 2021 · 9 comments
Closed

Detect web extensions #106

abrahamjuliot opened this issue Jan 6, 2021 · 9 comments
Labels
enhancement New feature or request revisit

Comments

@abrahamjuliot
Copy link
Owner

abrahamjuliot commented Jan 6, 2021

Detecting extensions in a chromium browser is rather candid. The manifest.json file can be viewed in a non-incognito window and under web_accessible_resources, the paths here are public, and then the list of public files can be obtained from the system folder.

For example, this will detect Grammarly

fetch('chrome-extension://kbfnbcaeplbcioakkpcpgfkobkghlhen/src/css/Grammarly.styles.css')
.then(() => console.log('extension found'))
.catch(error => console.log('extension not found'))

Chrome Profile Path is at chrome://version/

Steps to obtain resources:

  • example: open chrome-extension://chlffgpmiacpedhhbkiomidkjlcfhogd/manifest.json
  • resources are listed in web_accessible_resources

How to get webstore links

  • example: https://chrome.google.com/webstore/category/collection/wfh
  • [...document.querySelectorAll('.webstore-test-wall-tile a')].map(x => x.href)

Concept

getChromeExtensions = async () => {
    const extensions = {
        'aapbdbdomjkkjkaonfhkkikfgjllcleb': { name: 'Google Translate', file: 'popup_css_compiled.css' },
        'fake': { name: 'fake', file: 'broken.css' },
        'kbfnbcaeplbcioakkpcpgfkobkghlhen': { name: 'Grammarly', file: 'src/css/Grammarly.styles.css' },
        'kgjfgplpablkjnlkjmjdecgdpfankdle': { name: 'Zoom Scheduler', file: 'images/icon.svg'}
    }
    const urls = Object.keys(extensions).map(key => `chrome-extension://${key}/${extensions[key].file}`)
    const idMatcher = /\/\/([^\/]+)/
    const getName = res => extensions[idMatcher.exec(res.url)[1]].name
    console.log(urls)
    const result = Promise.all(urls.map(url => fetch(url).then(getName).catch(e => {}))).then(res => res.filter(x => !!x))
    return result
}
await getChromeExtensions()
@abrahamjuliot abrahamjuliot added the enhancement New feature or request label Jan 6, 2021
@abrahamjuliot
Copy link
Owner Author

abrahamjuliot commented Jan 6, 2021

Firefox addons can be targeted and identified through JS and CSS behavior detection, but (as far as I know) the limit with this method is the behavior is not consistent across sites and the code is subject to change. But, with this method, it would still be easy to rate the probability of the extension being used based on known behavior.

@abrahamjuliot
Copy link
Owner Author

abrahamjuliot commented Jan 7, 2021

Source viewer: https://chrome.google.com/webstore/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin

Popular:

Google Translate
Adobe Acrobat
Tampermonkey
Avast Online Security
Adblock Plus
Adblock
uBlock Origin
Pinterest Save Button
Cisco Webex
Grammarly for Chrome
Skype
Avast SafePrice
Honey

Bitwarded (3K+ stars): chrome-extension://nngceckbapebfimnlniiiahkandclblb/images/icon38.png
Zoom Scheduler (900+ stars): chrome-extension://kgjfgplpablkjnlkjmjdecgdpfankdle/images/icon.svg

abrahamjuliot added a commit that referenced this issue Jan 7, 2021
@abrahamjuliot
Copy link
Owner Author

abrahamjuliot added a commit that referenced this issue Jan 8, 2021
abrahamjuliot added a commit that referenced this issue Jan 8, 2021
@abrahamjuliot
Copy link
Owner Author

uBO filters (cosmetic)

<div class="glx-teaser">glx-teaser</div>
<div class="inplayer-ad">inplayer-ad</div>
<div class="inplayer_banners">inplayer_banners</div>
<div class="in_stream_banner">in_stream_banner</div>
<div class="dbanner">dbanner</div>
<div class="preroll-blocker">preroll-blocker</div>
<div class="happy-inside-player">happy-inside-player</div>
<div>safe</div>

@Niek
Copy link
Contributor

Niek commented May 11, 2021

This can also be used to detect Chromium vs Chrome. The official Chrome build comes with a couple of extensions such as the cast one.

@Thorin-Oakenpants
Copy link

Thorin-Oakenpants commented Jun 14, 2021

in Firefox what is shifted, or added, after constructor in iframe.contentWindow properties can be very telling

here is AdBlocker Ultimate (2nd highest number of users on Firefox)

  • edit: even if you WHITELIST the webpage/site 👀
"Array"
​"Element"
​"HTMLElement"
​"HTMLFrameElement"
​"HTMLIFrameElement"
​"HTMLObjectElement"
​"RTCPeerConnection"
​"String"
​"WeakSet"
​"decodeURI"
"decodeURIComponent"
​"encodeURI"
​"encodeURIComponent"
​"escape"
​"unescape"

@abrahamjuliot
Copy link
Owner Author

Nice. I might use that. I'm looking for a 2nd detection method to improve the current technique I'm working on in 8a8917d. Right now the section is focused on detecting resistance but it also detects extensions based on unique patterns in prototype lie details and relies on a stable set of APIs present with minimal extension settings.

@Thorin-Oakenpants
Copy link

here is AdBlocker Ultimate (2nd highest number of users on Firefox)

NFI why it came up as No. 2, it's actually No. 7. Adblock Plus is No. 1 and has the same result

@abrahamjuliot
Copy link
Owner Author

Initial concept is live at https://abrahamjuliot.github.io/creepjs/tests/extensions.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request revisit
Projects
None yet
Development

No branches or pull requests

3 participants