@zorilla/puppeteer-extra-plugin-stealth 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +21 -0
- package/LICENSE +21 -0
- package/README.md +324 -0
- package/dist/evasions/README.md +13 -0
- package/dist/evasions/_template/README.md +18 -0
- package/dist/evasions/_template/index.d.ts +13 -0
- package/dist/evasions/_template/index.d.ts.map +1 -0
- package/dist/evasions/_template/index.js +26 -0
- package/dist/evasions/_template/index.js.map +1 -0
- package/dist/evasions/_template/package.json +5 -0
- package/dist/evasions/_utils/README.md +287 -0
- package/dist/evasions/_utils/index.d.ts +238 -0
- package/dist/evasions/_utils/index.d.ts.map +1 -0
- package/dist/evasions/_utils/index.js +588 -0
- package/dist/evasions/_utils/index.js.map +1 -0
- package/dist/evasions/_utils/withUtils.d.ts +12 -0
- package/dist/evasions/_utils/withUtils.d.ts.map +1 -0
- package/dist/evasions/_utils/withUtils.js +47 -0
- package/dist/evasions/_utils/withUtils.js.map +1 -0
- package/dist/evasions/chrome.app/README.md +16 -0
- package/dist/evasions/chrome.app/index.d.ts +11 -0
- package/dist/evasions/chrome.app/index.d.ts.map +1 -0
- package/dist/evasions/chrome.app/index.js +97 -0
- package/dist/evasions/chrome.app/index.js.map +1 -0
- package/dist/evasions/chrome.app/package.json +5 -0
- package/dist/evasions/chrome.csi/README.md +29 -0
- package/dist/evasions/chrome.csi/index.d.ts +25 -0
- package/dist/evasions/chrome.csi/index.d.ts.map +1 -0
- package/dist/evasions/chrome.csi/index.js +69 -0
- package/dist/evasions/chrome.csi/index.js.map +1 -0
- package/dist/evasions/chrome.csi/package.json +5 -0
- package/dist/evasions/chrome.loadTimes/README.md +27 -0
- package/dist/evasions/chrome.loadTimes/index.d.ts +23 -0
- package/dist/evasions/chrome.loadTimes/index.d.ts.map +1 -0
- package/dist/evasions/chrome.loadTimes/index.js +163 -0
- package/dist/evasions/chrome.loadTimes/index.js.map +1 -0
- package/dist/evasions/chrome.loadTimes/package.json +5 -0
- package/dist/evasions/chrome.runtime/README.md +32 -0
- package/dist/evasions/chrome.runtime/index.d.ts +14 -0
- package/dist/evasions/chrome.runtime/index.d.ts.map +1 -0
- package/dist/evasions/chrome.runtime/index.js +252 -0
- package/dist/evasions/chrome.runtime/index.js.map +1 -0
- package/dist/evasions/chrome.runtime/package.json +5 -0
- package/dist/evasions/chrome.runtime/staticData.json +41 -0
- package/dist/evasions/defaultArgs/README.md +17 -0
- package/dist/evasions/defaultArgs/index.d.ts +2 -0
- package/dist/evasions/defaultArgs/index.d.ts.map +1 -0
- package/dist/evasions/defaultArgs/index.js +43 -0
- package/dist/evasions/defaultArgs/index.js.map +1 -0
- package/dist/evasions/defaultArgs/package.json +5 -0
- package/dist/evasions/iframe.contentWindow/README.md +19 -0
- package/dist/evasions/iframe.contentWindow/index.d.ts +15 -0
- package/dist/evasions/iframe.contentWindow/index.d.ts.map +1 -0
- package/dist/evasions/iframe.contentWindow/index.js +132 -0
- package/dist/evasions/iframe.contentWindow/index.js.map +1 -0
- package/dist/evasions/iframe.contentWindow/package.json +5 -0
- package/dist/evasions/media.codecs/README.md +38 -0
- package/dist/evasions/media.codecs/index.d.ts +12 -0
- package/dist/evasions/media.codecs/index.d.ts.map +1 -0
- package/dist/evasions/media.codecs/index.js +89 -0
- package/dist/evasions/media.codecs/index.js.map +1 -0
- package/dist/evasions/media.codecs/package.json +5 -0
- package/dist/evasions/navigator.hardwareConcurrency/README.md +19 -0
- package/dist/evasions/navigator.hardwareConcurrency/index.d.ts +2 -0
- package/dist/evasions/navigator.hardwareConcurrency/index.d.ts.map +1 -0
- package/dist/evasions/navigator.hardwareConcurrency/index.js +45 -0
- package/dist/evasions/navigator.hardwareConcurrency/index.js.map +1 -0
- package/dist/evasions/navigator.hardwareConcurrency/package.json +5 -0
- package/dist/evasions/navigator.languages/README.md +17 -0
- package/dist/evasions/navigator.languages/index.d.ts +2 -0
- package/dist/evasions/navigator.languages/index.d.ts.map +1 -0
- package/dist/evasions/navigator.languages/index.js +44 -0
- package/dist/evasions/navigator.languages/index.js.map +1 -0
- package/dist/evasions/navigator.languages/package.json +5 -0
- package/dist/evasions/navigator.permissions/README.md +16 -0
- package/dist/evasions/navigator.permissions/index.d.ts +2 -0
- package/dist/evasions/navigator.permissions/index.d.ts.map +1 -0
- package/dist/evasions/navigator.permissions/index.js +66 -0
- package/dist/evasions/navigator.permissions/index.js.map +1 -0
- package/dist/evasions/navigator.permissions/package.json +5 -0
- package/dist/evasions/navigator.plugins/README.md +24 -0
- package/dist/evasions/navigator.plugins/data.json +48 -0
- package/dist/evasions/navigator.plugins/functionMocks.d.ts +9 -0
- package/dist/evasions/navigator.plugins/functionMocks.d.ts.map +1 -0
- package/dist/evasions/navigator.plugins/functionMocks.js +47 -0
- package/dist/evasions/navigator.plugins/functionMocks.js.map +1 -0
- package/dist/evasions/navigator.plugins/index.d.ts +19 -0
- package/dist/evasions/navigator.plugins/index.d.ts.map +1 -0
- package/dist/evasions/navigator.plugins/index.js +98 -0
- package/dist/evasions/navigator.plugins/index.js.map +1 -0
- package/dist/evasions/navigator.plugins/magicArray.d.ts +2 -0
- package/dist/evasions/navigator.plugins/magicArray.d.ts.map +1 -0
- package/dist/evasions/navigator.plugins/magicArray.js +145 -0
- package/dist/evasions/navigator.plugins/magicArray.js.map +1 -0
- package/dist/evasions/navigator.plugins/mimeTypes.d.ts +2 -0
- package/dist/evasions/navigator.plugins/mimeTypes.d.ts.map +1 -0
- package/dist/evasions/navigator.plugins/mimeTypes.js +18 -0
- package/dist/evasions/navigator.plugins/mimeTypes.js.map +1 -0
- package/dist/evasions/navigator.plugins/package.json +5 -0
- package/dist/evasions/navigator.plugins/plugins.d.ts +2 -0
- package/dist/evasions/navigator.plugins/plugins.d.ts.map +1 -0
- package/dist/evasions/navigator.plugins/plugins.js +18 -0
- package/dist/evasions/navigator.plugins/plugins.js.map +1 -0
- package/dist/evasions/navigator.vendor/README.md +36 -0
- package/dist/evasions/navigator.vendor/index.d.ts +2 -0
- package/dist/evasions/navigator.vendor/index.d.ts.map +1 -0
- package/dist/evasions/navigator.vendor/index.js +64 -0
- package/dist/evasions/navigator.vendor/index.js.map +1 -0
- package/dist/evasions/navigator.vendor/package.json +5 -0
- package/dist/evasions/navigator.webdriver/README.md +17 -0
- package/dist/evasions/navigator.webdriver/index.d.ts +13 -0
- package/dist/evasions/navigator.webdriver/index.d.ts.map +1 -0
- package/dist/evasions/navigator.webdriver/index.js +48 -0
- package/dist/evasions/navigator.webdriver/index.js.map +1 -0
- package/dist/evasions/navigator.webdriver/package.json +5 -0
- package/dist/evasions/sourceurl/README.md +17 -0
- package/dist/evasions/sourceurl/_fixtures/test.html +35 -0
- package/dist/evasions/sourceurl/index.d.ts +12 -0
- package/dist/evasions/sourceurl/index.d.ts.map +1 -0
- package/dist/evasions/sourceurl/index.js +82 -0
- package/dist/evasions/sourceurl/index.js.map +1 -0
- package/dist/evasions/sourceurl/package.json +5 -0
- package/dist/evasions/user-agent-override/README.md +53 -0
- package/dist/evasions/user-agent-override/index.d.ts +2 -0
- package/dist/evasions/user-agent-override/index.d.ts.map +1 -0
- package/dist/evasions/user-agent-override/index.js +206 -0
- package/dist/evasions/user-agent-override/index.js.map +1 -0
- package/dist/evasions/user-agent-override/package.json +5 -0
- package/dist/evasions/webgl.vendor/README.md +20 -0
- package/dist/evasions/webgl.vendor/index.d.ts +17 -0
- package/dist/evasions/webgl.vendor/index.d.ts.map +1 -0
- package/dist/evasions/webgl.vendor/index.js +57 -0
- package/dist/evasions/webgl.vendor/index.js.map +1 -0
- package/dist/evasions/webgl.vendor/package.json +5 -0
- package/dist/evasions/window.outerdimensions/README.md +17 -0
- package/dist/evasions/window.outerdimensions/index.d.ts +13 -0
- package/dist/evasions/window.outerdimensions/index.d.ts.map +1 -0
- package/dist/evasions/window.outerdimensions/index.js +42 -0
- package/dist/evasions/window.outerdimensions/index.js.map +1 -0
- package/dist/evasions/window.outerdimensions/package.json +5 -0
- package/dist/index.d.ts +130 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +164 -0
- package/dist/index.js.map +1 -0
- package/examples/detect-headless.js +95 -0
- package/examples/test1.js +20 -0
- package/examples/test2.js +25 -0
- package/package.json +70 -0
- package/src/evasions/README.md +13 -0
- package/src/evasions/_template/README.md +18 -0
- package/src/evasions/_template/index.js +26 -0
- package/src/evasions/_template/package.json +5 -0
- package/src/evasions/_utils/README.md +287 -0
- package/src/evasions/_utils/index.js +588 -0
- package/src/evasions/_utils/withUtils.js +47 -0
- package/src/evasions/chrome.app/README.md +16 -0
- package/src/evasions/chrome.app/index.js +97 -0
- package/src/evasions/chrome.app/package.json +5 -0
- package/src/evasions/chrome.csi/README.md +29 -0
- package/src/evasions/chrome.csi/index.js +69 -0
- package/src/evasions/chrome.csi/package.json +5 -0
- package/src/evasions/chrome.loadTimes/README.md +27 -0
- package/src/evasions/chrome.loadTimes/index.js +163 -0
- package/src/evasions/chrome.loadTimes/package.json +5 -0
- package/src/evasions/chrome.runtime/README.md +32 -0
- package/src/evasions/chrome.runtime/index.js +252 -0
- package/src/evasions/chrome.runtime/package.json +5 -0
- package/src/evasions/chrome.runtime/staticData.json +41 -0
- package/src/evasions/defaultArgs/README.md +17 -0
- package/src/evasions/defaultArgs/index.js +43 -0
- package/src/evasions/defaultArgs/package.json +5 -0
- package/src/evasions/iframe.contentWindow/README.md +19 -0
- package/src/evasions/iframe.contentWindow/index.js +132 -0
- package/src/evasions/iframe.contentWindow/package.json +5 -0
- package/src/evasions/media.codecs/README.md +38 -0
- package/src/evasions/media.codecs/index.js +89 -0
- package/src/evasions/media.codecs/package.json +5 -0
- package/src/evasions/navigator.hardwareConcurrency/README.md +19 -0
- package/src/evasions/navigator.hardwareConcurrency/index.js +45 -0
- package/src/evasions/navigator.hardwareConcurrency/package.json +5 -0
- package/src/evasions/navigator.languages/README.md +17 -0
- package/src/evasions/navigator.languages/index.js +44 -0
- package/src/evasions/navigator.languages/package.json +5 -0
- package/src/evasions/navigator.permissions/README.md +16 -0
- package/src/evasions/navigator.permissions/index.js +66 -0
- package/src/evasions/navigator.permissions/package.json +5 -0
- package/src/evasions/navigator.plugins/README.md +24 -0
- package/src/evasions/navigator.plugins/data.json +48 -0
- package/src/evasions/navigator.plugins/functionMocks.js +47 -0
- package/src/evasions/navigator.plugins/index.js +98 -0
- package/src/evasions/navigator.plugins/magicArray.js +145 -0
- package/src/evasions/navigator.plugins/mimeTypes.js +18 -0
- package/src/evasions/navigator.plugins/package.json +5 -0
- package/src/evasions/navigator.plugins/plugins.js +18 -0
- package/src/evasions/navigator.vendor/README.md +36 -0
- package/src/evasions/navigator.vendor/index.js +64 -0
- package/src/evasions/navigator.vendor/package.json +5 -0
- package/src/evasions/navigator.webdriver/README.md +17 -0
- package/src/evasions/navigator.webdriver/index.js +48 -0
- package/src/evasions/navigator.webdriver/package.json +5 -0
- package/src/evasions/sourceurl/README.md +17 -0
- package/src/evasions/sourceurl/_fixtures/test.html +35 -0
- package/src/evasions/sourceurl/index.js +82 -0
- package/src/evasions/sourceurl/package.json +5 -0
- package/src/evasions/user-agent-override/README.md +53 -0
- package/src/evasions/user-agent-override/index.js +206 -0
- package/src/evasions/user-agent-override/package.json +5 -0
- package/src/evasions/webgl.vendor/README.md +20 -0
- package/src/evasions/webgl.vendor/index.js +57 -0
- package/src/evasions/webgl.vendor/package.json +5 -0
- package/src/evasions/window.outerdimensions/README.md +17 -0
- package/src/evasions/window.outerdimensions/index.js +42 -0
- package/src/evasions/window.outerdimensions/package.json +5 -0
- package/src/index.d.ts +111 -0
- package/src/index.ts +188 -0
- package/test/cat-and-mouse.test.ts +170 -0
- package/test/evasions/_utils/index.test.ts +710 -0
- package/test/evasions/chrome.app/index.test.ts +69 -0
- package/test/evasions/chrome.csi/index.test.ts +46 -0
- package/test/evasions/chrome.loadTimes/index.test.ts +61 -0
- package/test/evasions/chrome.runtime/index.test.ts +282 -0
- package/test/evasions/defaultArgs/index.test.ts +36 -0
- package/test/evasions/iframe.contentWindow/index.test.js +450 -0
- package/test/evasions/media.codecs/index.test.js +103 -0
- package/test/evasions/navigator.hardwareConcurrency/index.test.js +58 -0
- package/test/evasions/navigator.languages/index.test.js +101 -0
- package/test/evasions/navigator.permissions/index.test.js +104 -0
- package/test/evasions/navigator.plugins/index.test.js +55 -0
- package/test/evasions/navigator.plugins/mimeTypes.test.js +220 -0
- package/test/evasions/navigator.plugins/plugins.test.js +181 -0
- package/test/evasions/navigator.vendor/index.test.js +68 -0
- package/test/evasions/navigator.webdriver/index.test.js +47 -0
- package/test/evasions/sourceurl/_fixtures/test.html +35 -0
- package/test/evasions/sourceurl/index.test.js +62 -0
- package/test/evasions/user-agent-override/index.test.js +338 -0
- package/test/evasions/webgl.vendor/index.test.js +220 -0
- package/test/fixtures/dummy-with-service-worker.html +22 -0
- package/test/fixtures/dummy.html +11 -0
- package/test/fixtures/sw.js +1 -0
- package/test/fpscanner.test.ts +54 -0
- package/test/index.test.ts +51 -0
- package/test/service-worker.test.ts +112 -0
- package/test/stealth/_results/_thumbs/headful-chrome-stealth.js.png +0 -0
- package/test/stealth/_results/_thumbs/headful-chrome-vanilla.js.png +0 -0
- package/test/stealth/_results/_thumbs/headful-chromium-stealth.js.png +0 -0
- package/test/stealth/_results/_thumbs/headful-chromium-vanilla.js.png +0 -0
- package/test/stealth/_results/_thumbs/headless-chrome-stealth.js.png +0 -0
- package/test/stealth/_results/_thumbs/headless-chrome-vanilla.js.png +0 -0
- package/test/stealth/_results/_thumbs/headless-chromium-stealth.js.png +0 -0
- package/test/stealth/_results/_thumbs/headless-chromium-vanilla.js.png +0 -0
- package/test/stealth/_results/headful-chrome-stealth.js.png +0 -0
- package/test/stealth/_results/headful-chrome-vanilla.js.png +0 -0
- package/test/stealth/_results/headful-chromium-stealth.js.png +0 -0
- package/test/stealth/_results/headful-chromium-vanilla.js.png +0 -0
- package/test/stealth/_results/headless-chrome-stealth.js.png +0 -0
- package/test/stealth/_results/headless-chrome-vanilla.js.png +0 -0
- package/test/stealth/_results/headless-chromium-stealth.js.png +0 -0
- package/test/stealth/_results/headless-chromium-vanilla.js.png +0 -0
- package/test/stealth/headful-chrome-stealth.js +25 -0
- package/test/stealth/headful-chrome-vanilla.js +23 -0
- package/test/stealth/headful-chromium-stealth.js +22 -0
- package/test/stealth/headful-chromium-vanilla.js +20 -0
- package/test/stealth/headless-chrome-stealth.js +25 -0
- package/test/stealth/headless-chrome-vanilla.js +23 -0
- package/test/stealth/headless-chromium-stealth.js +22 -0
- package/test/stealth/headless-chromium-vanilla.js +20 -0
- package/test/util.js +82 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +28 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
## API
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
#### Table of Contents
|
|
5
|
+
|
|
6
|
+
- [class: Plugin](#class-plugin)
|
|
7
|
+
|
|
8
|
+
### class: [Plugin](https://github.com/zorillajs/zorilla/blob/ab0047d1af7dc38412744abdb61bcfc35c42dc34/packages/puppeteer-extra-plugin-stealth/evasions/user-agent-override/index.js#L42-L203)
|
|
9
|
+
|
|
10
|
+
- `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Options (optional, default `{}`)
|
|
11
|
+
- `opts.userAgent` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The user agent to use (default: browser.userAgent())
|
|
12
|
+
- `opts.locale` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The locale to use in `Accept-Language` header and in `navigator.languages` (default: `en-US,en`)
|
|
13
|
+
- `opts.maskLinux` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Wether to hide Linux as platform in the user agent or not - true by default
|
|
14
|
+
|
|
15
|
+
**Extends: PuppeteerExtraPlugin**
|
|
16
|
+
|
|
17
|
+
Fixes the UserAgent info (composed of UA string, Accept-Language, Platform, and UA hints).
|
|
18
|
+
|
|
19
|
+
If you don't provide any values this plugin will default to using the regular UserAgent string (while stripping the headless part).
|
|
20
|
+
Default language is set to "en-US,en", the other settings match the UserAgent string.
|
|
21
|
+
If you are running on Linux, it will mask the settins to look like Windows. This behavior can be disabled with the `maskLinux` option.
|
|
22
|
+
|
|
23
|
+
By default puppeteer will not set a `Accept-Language` header in headless:
|
|
24
|
+
It's (theoretically) possible to fix that using either `page.setExtraHTTPHeaders` or a `--lang` launch arg.
|
|
25
|
+
Unfortunately `page.setExtraHTTPHeaders` will lowercase everything and launch args are not always available. :)
|
|
26
|
+
|
|
27
|
+
In addition, the `navigator.platform` property is always set to the host value, e.g. `Linux` which makes detection very easy.
|
|
28
|
+
|
|
29
|
+
Note: You cannot use the regular `page.setUserAgent()` puppeteer call in your code,
|
|
30
|
+
as it will reset the language and platform values you set with this plugin.
|
|
31
|
+
|
|
32
|
+
Example:
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
const puppeteer = require('@zorilla/puppeteer-extra')
|
|
36
|
+
|
|
37
|
+
const StealthPlugin = require('@zorilla/puppeteer-extra-plugin-stealth')
|
|
38
|
+
const stealth = StealthPlugin()
|
|
39
|
+
// Remove this specific stealth plugin from the default set
|
|
40
|
+
stealth.enabledEvasions.delete('user-agent-override')
|
|
41
|
+
puppeteer.use(stealth)
|
|
42
|
+
|
|
43
|
+
// Stealth plugins are just regular `puppeteer-extra` plugins and can be added as such
|
|
44
|
+
const UserAgentOverride = require('@zorilla/puppeteer-extra-plugin-stealth/evasions/user-agent-override')
|
|
45
|
+
// Define custom UA and locale
|
|
46
|
+
const ua = UserAgentOverride({
|
|
47
|
+
userAgent: 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)',
|
|
48
|
+
locale: 'de-DE,de'
|
|
49
|
+
})
|
|
50
|
+
puppeteer.use(ua)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/evasions/user-agent-override/index.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { PuppeteerExtraPlugin } from '@zorilla/puppeteer-extra-plugin';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Fixes the UserAgent info (composed of UA string, Accept-Language, Platform, and UA hints).
|
|
5
|
+
*
|
|
6
|
+
* If you don't provide any values this plugin will default to using the regular UserAgent string (while stripping the headless part).
|
|
7
|
+
* Default language is set to "en-US,en", the other settings match the UserAgent string.
|
|
8
|
+
* If you are running on Linux, it will mask the settins to look like Windows. This behavior can be disabled with the `maskLinux` option.
|
|
9
|
+
*
|
|
10
|
+
* By default puppeteer will not set a `Accept-Language` header in headless:
|
|
11
|
+
* It's (theoretically) possible to fix that using either `page.setExtraHTTPHeaders` or a `--lang` launch arg.
|
|
12
|
+
* Unfortunately `page.setExtraHTTPHeaders` will lowercase everything and launch args are not always available. :)
|
|
13
|
+
*
|
|
14
|
+
* In addition, the `navigator.platform` property is always set to the host value, e.g. `Linux` which makes detection very easy.
|
|
15
|
+
*
|
|
16
|
+
* Note: You cannot use the regular `page.setUserAgent()` puppeteer call in your code,
|
|
17
|
+
* as it will reset the language and platform values you set with this plugin.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const puppeteer = require("puppeteer-extra")
|
|
21
|
+
*
|
|
22
|
+
* const StealthPlugin = require("puppeteer-extra-plugin-stealth")
|
|
23
|
+
* const stealth = StealthPlugin()
|
|
24
|
+
* // Remove this specific stealth plugin from the default set
|
|
25
|
+
* stealth.enabledEvasions.delete("user-agent-override")
|
|
26
|
+
* puppeteer.use(stealth)
|
|
27
|
+
*
|
|
28
|
+
* // Stealth plugins are just regular `puppeteer-extra` plugins and can be added as such
|
|
29
|
+
* const UserAgentOverride = require("puppeteer-extra-plugin-stealth/evasions/user-agent-override")
|
|
30
|
+
* // Define custom UA and locale
|
|
31
|
+
* const ua = UserAgentOverride({ userAgent: "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)", locale: "de-DE,de" })
|
|
32
|
+
* puppeteer.use(ua)
|
|
33
|
+
*
|
|
34
|
+
* @param {Object} [opts] - Options
|
|
35
|
+
* @param {string} [opts.userAgent] - The user agent to use (default: browser.userAgent())
|
|
36
|
+
* @param {string} [opts.locale] - The locale to use in `Accept-Language` header and in `navigator.languages` (default: `en-US,en`)
|
|
37
|
+
* @param {boolean} [opts.maskLinux] - Wether to hide Linux as platform in the user agent or not - true by default
|
|
38
|
+
*
|
|
39
|
+
*/
|
|
40
|
+
class Plugin extends PuppeteerExtraPlugin {
|
|
41
|
+
constructor(opts = {}) {
|
|
42
|
+
super(opts);
|
|
43
|
+
|
|
44
|
+
this._headless = false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get name() {
|
|
48
|
+
return 'stealth/evasions/user-agent-override';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
get dependencies() {
|
|
52
|
+
return new Set(['user-preferences']);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get defaults() {
|
|
56
|
+
return {
|
|
57
|
+
userAgent: null,
|
|
58
|
+
locale: 'en-US,en',
|
|
59
|
+
maskLinux: true,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async onPageCreated(page) {
|
|
64
|
+
// Determine the full user agent string, strip the "Headless" part
|
|
65
|
+
let ua =
|
|
66
|
+
this.opts.userAgent ||
|
|
67
|
+
(await page.browser().userAgent()).replace('HeadlessChrome/', 'Chrome/');
|
|
68
|
+
|
|
69
|
+
if (
|
|
70
|
+
this.opts.maskLinux &&
|
|
71
|
+
ua.includes('Linux') &&
|
|
72
|
+
!ua.includes('Android') // Skip Android user agents since they also contain Linux
|
|
73
|
+
) {
|
|
74
|
+
ua = ua.replace(/\(([^)]+)\)/, '(Windows NT 10.0; Win64; x64)'); // Replace the first part in parentheses with Windows data
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Full version number from Chrome
|
|
78
|
+
const uaVersion = ua.includes('Chrome/')
|
|
79
|
+
? ua.match(/Chrome\/([\d|.]+)/)[1]
|
|
80
|
+
: (await page.browser().version()).match(/\/([\d|.]+)/)[1];
|
|
81
|
+
|
|
82
|
+
// Get platform identifier (short or long version)
|
|
83
|
+
const _getPlatform = (extended = false) => {
|
|
84
|
+
if (ua.includes('Mac OS X')) {
|
|
85
|
+
return extended ? 'Mac OS X' : 'MacIntel';
|
|
86
|
+
} else if (ua.includes('Android')) {
|
|
87
|
+
return 'Android';
|
|
88
|
+
} else if (ua.includes('Linux')) {
|
|
89
|
+
return 'Linux';
|
|
90
|
+
} else {
|
|
91
|
+
return extended ? 'Windows' : 'Win32';
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// Source in C++: https://source.chromium.org/chromium/chromium/src/+/master:components/embedder_support/user_agent_utils.cc;l=55-100
|
|
96
|
+
const _getBrands = () => {
|
|
97
|
+
const seed = uaVersion.split('.')[0]; // the major version number of Chrome
|
|
98
|
+
|
|
99
|
+
const order = [
|
|
100
|
+
[0, 1, 2],
|
|
101
|
+
[0, 2, 1],
|
|
102
|
+
[1, 0, 2],
|
|
103
|
+
[1, 2, 0],
|
|
104
|
+
[2, 0, 1],
|
|
105
|
+
[2, 1, 0],
|
|
106
|
+
][seed % 6];
|
|
107
|
+
const escapedChars = [' ', ' ', ';'];
|
|
108
|
+
|
|
109
|
+
const greaseyBrand = `${escapedChars[order[0]]}Not${
|
|
110
|
+
escapedChars[order[1]]
|
|
111
|
+
}A${escapedChars[order[2]]}Brand`;
|
|
112
|
+
|
|
113
|
+
const greasedBrandVersionList = [];
|
|
114
|
+
greasedBrandVersionList[order[0]] = {
|
|
115
|
+
brand: greaseyBrand,
|
|
116
|
+
version: '99',
|
|
117
|
+
};
|
|
118
|
+
greasedBrandVersionList[order[1]] = {
|
|
119
|
+
brand: 'Chromium',
|
|
120
|
+
version: seed,
|
|
121
|
+
};
|
|
122
|
+
greasedBrandVersionList[order[2]] = {
|
|
123
|
+
brand: 'Google Chrome',
|
|
124
|
+
version: seed,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return greasedBrandVersionList;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Return OS version
|
|
131
|
+
const _getPlatformVersion = () => {
|
|
132
|
+
if (ua.includes('Mac OS X ')) {
|
|
133
|
+
return ua.match(/Mac OS X ([^)]+)/)[1];
|
|
134
|
+
} else if (ua.includes('Android ')) {
|
|
135
|
+
return ua.match(/Android ([^;]+)/)[1];
|
|
136
|
+
} else if (ua.includes('Windows ')) {
|
|
137
|
+
return ua.match(/Windows .*?([\d|.]+);?/)[1];
|
|
138
|
+
} else {
|
|
139
|
+
return '';
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// Get architecture, this seems to be empty on mobile and x86 on desktop
|
|
144
|
+
const _getPlatformArch = () => (_getMobile() ? '' : 'x86');
|
|
145
|
+
|
|
146
|
+
// Return the Android model, empty on desktop
|
|
147
|
+
const _getPlatformModel = () =>
|
|
148
|
+
_getMobile() ? ua.match(/Android.*?;\s([^)]+)/)[1] : '';
|
|
149
|
+
|
|
150
|
+
const _getMobile = () => ua.includes('Android');
|
|
151
|
+
|
|
152
|
+
const override = {
|
|
153
|
+
userAgent: ua,
|
|
154
|
+
platform: _getPlatform(),
|
|
155
|
+
userAgentMetadata: {
|
|
156
|
+
brands: _getBrands(),
|
|
157
|
+
fullVersion: uaVersion,
|
|
158
|
+
platform: _getPlatform(true),
|
|
159
|
+
platformVersion: _getPlatformVersion(),
|
|
160
|
+
architecture: _getPlatformArch(),
|
|
161
|
+
model: _getPlatformModel(),
|
|
162
|
+
mobile: _getMobile(),
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// In case of headless, override the acceptLanguage in CDP.
|
|
167
|
+
// This is not preferred, as it messed up the header order.
|
|
168
|
+
// On headful, we set the user preference language setting instead.
|
|
169
|
+
if (this._headless) {
|
|
170
|
+
override.acceptLanguage = this.opts.locale || 'en-US,en';
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
this.debug('onPageCreated - Will set these user agent options', {
|
|
174
|
+
override,
|
|
175
|
+
opts: this.opts,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
const client =
|
|
179
|
+
typeof page._client === 'function' ? page._client() : page._client;
|
|
180
|
+
client.send('Network.setUserAgentOverride', override);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async beforeLaunch(options) {
|
|
184
|
+
// Check if launched headless
|
|
185
|
+
this._headless = options.headless;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async beforeConnect() {
|
|
189
|
+
// Treat browsers using connect() as headless browsers
|
|
190
|
+
this._headless = true;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
get data() {
|
|
194
|
+
return [
|
|
195
|
+
{
|
|
196
|
+
name: 'userPreferences',
|
|
197
|
+
value: {
|
|
198
|
+
intl: { accept_languages: this.opts.locale || 'en-US,en' },
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
];
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const defaultExport = opts => new Plugin(opts);
|
|
206
|
+
module.exports = defaultExport;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/evasions/user-agent-override/index.js"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## API
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
#### Table of Contents
|
|
5
|
+
|
|
6
|
+
- [class: Plugin](#class-plugin)
|
|
7
|
+
|
|
8
|
+
### class: [Plugin](https://github.com/zorillajs/zorilla/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/webgl.vendor/index.js#L17-L55)
|
|
9
|
+
|
|
10
|
+
- `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Options (optional, default `{}`)
|
|
11
|
+
- `opts.vendor` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The vendor string to use (default: `Intel Inc.`)
|
|
12
|
+
- `opts.renderer` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The renderer string (default: `Intel Iris OpenGL Engine`)
|
|
13
|
+
|
|
14
|
+
**Extends: PuppeteerExtraPlugin**
|
|
15
|
+
|
|
16
|
+
Fix WebGL Vendor/Renderer being set to Google in headless mode
|
|
17
|
+
|
|
18
|
+
Example data (Apple Retina MBP 13): {vendor: "Intel Inc.", renderer: "Intel(R) Iris(TM) Graphics 6100"}
|
|
19
|
+
|
|
20
|
+
---
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export default function _default(pluginConfig: any): Plugin;
|
|
2
|
+
/**
|
|
3
|
+
* Fix WebGL Vendor/Renderer being set to Google in headless mode
|
|
4
|
+
*
|
|
5
|
+
* Example data (Apple Retina MBP 13): {vendor: "Intel Inc.", renderer: "Intel(R) Iris(TM) Graphics 6100"}
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} [opts] - Options
|
|
8
|
+
* @param {string} [opts.vendor] - The vendor string to use (default: `Intel Inc.`)
|
|
9
|
+
* @param {string} [opts.renderer] - The renderer string (default: `Intel Iris OpenGL Engine`)
|
|
10
|
+
*/
|
|
11
|
+
declare class Plugin extends PuppeteerExtraPlugin {
|
|
12
|
+
constructor(opts?: {});
|
|
13
|
+
onPageCreated(page: any): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
import { PuppeteerExtraPlugin } from '@zorilla/puppeteer-extra-plugin';
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/evasions/webgl.vendor/index.js"],"names":[],"mappings":"AAsDA,4DAEC;AApDD;;;;;;;;GAQG;AACH;IACE,uBAEC;IAOD,wCA4BC;CACF;qCApDoC,iCAAiC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { PuppeteerExtraPlugin } from '@zorilla/puppeteer-extra-plugin';
|
|
2
|
+
|
|
3
|
+
import withUtils from '../_utils/withUtils.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Fix WebGL Vendor/Renderer being set to Google in headless mode
|
|
7
|
+
*
|
|
8
|
+
* Example data (Apple Retina MBP 13): {vendor: "Intel Inc.", renderer: "Intel(R) Iris(TM) Graphics 6100"}
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} [opts] - Options
|
|
11
|
+
* @param {string} [opts.vendor] - The vendor string to use (default: `Intel Inc.`)
|
|
12
|
+
* @param {string} [opts.renderer] - The renderer string (default: `Intel Iris OpenGL Engine`)
|
|
13
|
+
*/
|
|
14
|
+
class Plugin extends PuppeteerExtraPlugin {
|
|
15
|
+
constructor(opts = {}) {
|
|
16
|
+
super(opts);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get name() {
|
|
20
|
+
return 'stealth/evasions/webgl.vendor';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* global WebGLRenderingContext WebGL2RenderingContext */
|
|
24
|
+
async onPageCreated(page) {
|
|
25
|
+
await withUtils(page).evaluateOnNewDocument((utils, opts) => {
|
|
26
|
+
const getParameterProxyHandler = {
|
|
27
|
+
apply: (target, ctx, args) => {
|
|
28
|
+
const param = (args || [])[0];
|
|
29
|
+
const result = utils.cache.Reflect.apply(target, ctx, args);
|
|
30
|
+
// UNMASKED_VENDOR_WEBGL
|
|
31
|
+
if (param === 37445) {
|
|
32
|
+
return opts.vendor || 'Intel Inc.'; // default in headless: Google Inc.
|
|
33
|
+
}
|
|
34
|
+
// UNMASKED_RENDERER_WEBGL
|
|
35
|
+
if (param === 37446) {
|
|
36
|
+
return opts.renderer || 'Intel Iris OpenGL Engine'; // default in headless: Google SwiftShader
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// There's more than one WebGL rendering context
|
|
43
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext#Browser_compatibility
|
|
44
|
+
// To find out the original values here: Object.getOwnPropertyDescriptors(WebGLRenderingContext.prototype.getParameter)
|
|
45
|
+
const addProxy = (obj, propName) => {
|
|
46
|
+
utils.replaceWithProxy(obj, propName, getParameterProxyHandler);
|
|
47
|
+
};
|
|
48
|
+
// For whatever weird reason loops don't play nice with Object.defineProperty, here's the next best thing:
|
|
49
|
+
addProxy(WebGLRenderingContext.prototype, 'getParameter');
|
|
50
|
+
addProxy(WebGL2RenderingContext.prototype, 'getParameter');
|
|
51
|
+
}, this.opts);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default function (pluginConfig) {
|
|
56
|
+
return new Plugin(pluginConfig);
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/evasions/webgl.vendor/index.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,SAAS,MAAM,wBAAwB,CAAC;AAE/C;;;;;;;;GAQG;AACH,MAAM,MAAO,SAAQ,oBAAoB;IACvC,YAAY,IAAI,GAAG,EAAE;QACnB,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAED,IAAI,IAAI;QACN,OAAO,+BAA+B,CAAC;IACzC,CAAC;IAED,yDAAyD;IACzD,KAAK,CAAC,aAAa,CAAC,IAAI;QACtB,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC1D,MAAM,wBAAwB,GAAG;gBAC/B,KAAK,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;oBAC3B,MAAM,KAAK,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;oBAC5D,wBAAwB;oBACxB,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;wBACpB,OAAO,IAAI,CAAC,MAAM,IAAI,YAAY,CAAC,CAAC,mCAAmC;oBACzE,CAAC;oBACD,0BAA0B;oBAC1B,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;wBACpB,OAAO,IAAI,CAAC,QAAQ,IAAI,0BAA0B,CAAC,CAAC,0CAA0C;oBAChG,CAAC;oBACD,OAAO,MAAM,CAAC;gBAChB,CAAC;aACF,CAAC;YAEF,gDAAgD;YAChD,gGAAgG;YAChG,uHAAuH;YACvH,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE;gBACjC,KAAK,CAAC,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,wBAAwB,CAAC,CAAC;YAClE,CAAC,CAAC;YACF,0GAA0G;YAC1G,QAAQ,CAAC,qBAAqB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;YAC1D,QAAQ,CAAC,sBAAsB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAC7D,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;CACF;AAED,MAAM,CAAC,OAAO,WAAW,YAAY;IACnC,OAAO,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## API
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
#### Table of Contents
|
|
5
|
+
|
|
6
|
+
- [class: Plugin](#class-plugin)
|
|
7
|
+
|
|
8
|
+
### class: [Plugin](https://github.com/zorillajs/zorilla/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/window.outerdimensions/index.js#L9-L40)
|
|
9
|
+
|
|
10
|
+
- `opts` (optional, default `{}`)
|
|
11
|
+
|
|
12
|
+
**Extends: PuppeteerExtraPlugin**
|
|
13
|
+
|
|
14
|
+
Fix missing window.outerWidth/window.outerHeight in headless mode
|
|
15
|
+
Will also set the viewport to match window size, unless specified by user
|
|
16
|
+
|
|
17
|
+
---
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default function _default(pluginConfig: any): Plugin;
|
|
2
|
+
/**
|
|
3
|
+
* Fix missing window.outerWidth/window.outerHeight in headless mode
|
|
4
|
+
* Will also set the viewport to match window size, unless specified by user
|
|
5
|
+
*/
|
|
6
|
+
declare class Plugin extends PuppeteerExtraPlugin {
|
|
7
|
+
constructor(opts?: {});
|
|
8
|
+
onPageCreated(page: any): Promise<void>;
|
|
9
|
+
beforeLaunch(options: any): Promise<any>;
|
|
10
|
+
}
|
|
11
|
+
import { PuppeteerExtraPlugin } from '@zorilla/puppeteer-extra-plugin';
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/evasions/window.outerdimensions/index.js"],"names":[],"mappings":"AAuCA,4DAEC;AAvCD;;;GAGG;AACH;IACE,uBAEC;IAMD,wCAYC;IAED,yCAOC;CACF;qCArCoC,iCAAiC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { PuppeteerExtraPlugin } from '@zorilla/puppeteer-extra-plugin';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Fix missing window.outerWidth/window.outerHeight in headless mode
|
|
5
|
+
* Will also set the viewport to match window size, unless specified by user
|
|
6
|
+
*/
|
|
7
|
+
class Plugin extends PuppeteerExtraPlugin {
|
|
8
|
+
constructor(opts = {}) {
|
|
9
|
+
super(opts);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get name() {
|
|
13
|
+
return 'stealth/evasions/window.outerdimensions';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async onPageCreated(page) {
|
|
17
|
+
// Chrome returns undefined, Firefox false
|
|
18
|
+
await page.evaluateOnNewDocument(() => {
|
|
19
|
+
try {
|
|
20
|
+
if (window.outerWidth && window.outerHeight) {
|
|
21
|
+
return; // nothing to do here
|
|
22
|
+
}
|
|
23
|
+
const windowFrame = 85; // probably OS and WM dependent
|
|
24
|
+
window.outerWidth = window.innerWidth;
|
|
25
|
+
window.outerHeight = window.innerHeight + windowFrame;
|
|
26
|
+
} catch (_err) {}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async beforeLaunch(options) {
|
|
31
|
+
// Have viewport match window size, unless specified by user
|
|
32
|
+
// https://github.com/GoogleChrome/puppeteer/issues/3688
|
|
33
|
+
if (!('defaultViewport' in options)) {
|
|
34
|
+
options.defaultViewport = null;
|
|
35
|
+
}
|
|
36
|
+
return options;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default function (pluginConfig) {
|
|
41
|
+
return new Plugin(pluginConfig);
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/evasions/window.outerdimensions/index.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAO,SAAQ,oBAAoB;IACvC,YAAY,IAAI,GAAG,EAAE;QACnB,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAED,IAAI,IAAI;QACN,OAAO,yCAAyC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAI;QACtB,0CAA0C;QAC1C,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC;gBACH,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;oBAC5C,OAAO,CAAC,qBAAqB;gBAC/B,CAAC;gBACD,MAAM,WAAW,GAAG,EAAE,CAAC,CAAC,+BAA+B;gBACvD,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;gBACtC,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;YACxD,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC,CAAA,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAAO;QACxB,4DAA4D;QAC5D,wDAAwD;QACxD,IAAI,CAAC,CAAC,iBAAiB,IAAI,OAAO,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;QACjC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED,MAAM,CAAC,OAAO,WAAW,YAAY;IACnC,OAAO,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { PuppeteerExtraPlugin } from '@zorilla/puppeteer-extra-plugin';
|
|
2
|
+
import type * as Puppeteer from '@zorilla/puppeteer-extra-plugin/dist/puppeteer';
|
|
3
|
+
interface PluginOptions {
|
|
4
|
+
enabledEvasions?: Set<string>;
|
|
5
|
+
availableEvasions?: Set<string>;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
}
|
|
8
|
+
interface BrowserOptions {
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Stealth mode: Applies various techniques to make detection of headless puppeteer harder. 💯
|
|
13
|
+
*
|
|
14
|
+
* ### Purpose
|
|
15
|
+
* There are a couple of ways the use of puppeteer can easily be detected by a target website.
|
|
16
|
+
* The addition of `HeadlessChrome` to the user-agent being only the most obvious one.
|
|
17
|
+
*
|
|
18
|
+
* The goal of this plugin is to be the definite companion to puppeteer to avoid
|
|
19
|
+
* detection, applying new techniques as they surface.
|
|
20
|
+
*
|
|
21
|
+
* As this cat & mouse game is in it's infancy and fast-paced the plugin
|
|
22
|
+
* is kept as flexibile as possible, to support quick testing and iterations.
|
|
23
|
+
*
|
|
24
|
+
* ### Modularity
|
|
25
|
+
* This plugin uses `puppeteer-extra`'s dependency system to only require
|
|
26
|
+
* code mods for evasions that have been enabled, to keep things modular and efficient.
|
|
27
|
+
*
|
|
28
|
+
* The `stealth` plugin is a convenience wrapper that requires multiple [evasion techniques](./evasions/)
|
|
29
|
+
* automatically and comes with defaults. You could also bypass the main module and require
|
|
30
|
+
* specific evasion plugins yourself, if you whish to do so (as they're standalone `puppeteer-extra` plugins):
|
|
31
|
+
*
|
|
32
|
+
* ```es6
|
|
33
|
+
* // bypass main module and require a specific stealth plugin directly:
|
|
34
|
+
* puppeteer.use(require('@zorilla/puppeteer-extra-plugin-stealth/evasions/console.debug')())
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* ### Contributing
|
|
38
|
+
* PRs are welcome, if you want to add a new evasion technique I suggest you
|
|
39
|
+
* look at the [template](./evasions/_template) to kickstart things.
|
|
40
|
+
*
|
|
41
|
+
* ### Kudos
|
|
42
|
+
* Thanks to [Evan Sangaline](https://intoli.com/blog/not-possible-to-block-chrome-headless/) and [Paul Irish](https://github.com/paulirish/headless-cat-n-mouse) for kickstarting the discussion!
|
|
43
|
+
*
|
|
44
|
+
* ---
|
|
45
|
+
*
|
|
46
|
+
* @todo
|
|
47
|
+
* - white-/blacklist with url globs (make this a generic plugin method?)
|
|
48
|
+
* - dynamic whitelist based on function evaluation
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* const puppeteer = require('@zorilla/puppeteer-extra')
|
|
52
|
+
* // Enable stealth plugin with all evasions
|
|
53
|
+
* puppeteer.use(require('@zorilla/puppeteer-extra-plugin-stealth')())
|
|
54
|
+
*
|
|
55
|
+
*
|
|
56
|
+
* ;(async () => {
|
|
57
|
+
* // Launch the browser in headless mode and set up a page.
|
|
58
|
+
* const browser = await puppeteer.launch({ args: ['--no-sandbox'], headless: true })
|
|
59
|
+
* const page = await browser.newPage()
|
|
60
|
+
*
|
|
61
|
+
* // Navigate to the page that will perform the tests.
|
|
62
|
+
* const testUrl = 'https://intoli.com/blog/' +
|
|
63
|
+
* 'not-possible-to-block-chrome-headless/chrome-headless-test.html'
|
|
64
|
+
* await page.goto(testUrl)
|
|
65
|
+
*
|
|
66
|
+
* // Save a screenshot of the results.
|
|
67
|
+
* const screenshotPath = '/tmp/headless-test-result.png'
|
|
68
|
+
* await page.screenshot({path: screenshotPath})
|
|
69
|
+
* console.log('have a look at the screenshot:', screenshotPath)
|
|
70
|
+
*
|
|
71
|
+
* await browser.close()
|
|
72
|
+
* })()
|
|
73
|
+
*
|
|
74
|
+
* @param {Object} [opts] - Options
|
|
75
|
+
* @param {Set<string>} [opts.enabledEvasions] - Specify which evasions to use (by default all)
|
|
76
|
+
*
|
|
77
|
+
*/
|
|
78
|
+
declare class StealthPlugin extends PuppeteerExtraPlugin {
|
|
79
|
+
constructor(opts?: PluginOptions);
|
|
80
|
+
get name(): string;
|
|
81
|
+
get defaults(): Required<PluginOptions>;
|
|
82
|
+
/**
|
|
83
|
+
* Requires evasion techniques dynamically based on configuration.
|
|
84
|
+
*
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
get dependencies(): Set<string>;
|
|
88
|
+
/**
|
|
89
|
+
* Get all available evasions.
|
|
90
|
+
*
|
|
91
|
+
* Please look into the [evasions directory](./evasions/) for an up to date list.
|
|
92
|
+
*
|
|
93
|
+
* @type {Set<string>} - A Set of all available evasions.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* const pluginStealth = require('@zorilla/puppeteer-extra-plugin-stealth')()
|
|
97
|
+
* console.log(pluginStealth.availableEvasions) // => Set { 'user-agent', 'console.debug' }
|
|
98
|
+
* puppeteer.use(pluginStealth)
|
|
99
|
+
*/
|
|
100
|
+
get availableEvasions(): Set<string>;
|
|
101
|
+
/**
|
|
102
|
+
* Get all enabled evasions.
|
|
103
|
+
*
|
|
104
|
+
* Enabled evasions can be configured either through `opts` or by modifying this property.
|
|
105
|
+
*
|
|
106
|
+
* @type {Set<string>} - A Set of all enabled evasions.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* // Remove specific evasion from enabled ones dynamically
|
|
110
|
+
* const pluginStealth = require('@zorilla/puppeteer-extra-plugin-stealth')()
|
|
111
|
+
* pluginStealth.enabledEvasions.delete('console.debug')
|
|
112
|
+
* puppeteer.use(pluginStealth)
|
|
113
|
+
*/
|
|
114
|
+
get enabledEvasions(): Set<string>;
|
|
115
|
+
/**
|
|
116
|
+
* @private
|
|
117
|
+
*/
|
|
118
|
+
set enabledEvasions(evasions: Set<string>);
|
|
119
|
+
onBrowser(browser: Puppeteer.Browser, _opts: BrowserOptions): Promise<void>;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Default export, PuppeteerExtraStealthPlugin
|
|
123
|
+
*
|
|
124
|
+
* @param {Object} [opts] - Options
|
|
125
|
+
* @param {Set<string>} [opts.enabledEvasions] - Specify which evasions to use (by default all)
|
|
126
|
+
*/
|
|
127
|
+
declare const _default: (opts?: PluginOptions) => StealthPlugin;
|
|
128
|
+
export default _default;
|
|
129
|
+
export { StealthPlugin };
|
|
130
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,KAAK,SAAS,MAAM,gDAAgD,CAAC;AAEjF,UAAU,aAAa;IACrB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,UAAU,cAAc;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,cAAM,aAAc,SAAQ,oBAAoB;gBAClC,IAAI,GAAE,aAAkB;IAIpC,IAAa,IAAI,IAAI,MAAM,CAE1B;IAED,IAAa,QAAQ,IAAI,QAAQ,CAAC,aAAa,CAAC,CAwB/C;IAED;;;;OAIG;IACH,IAAa,YAAY,IAAI,GAAG,CAAC,MAAM,CAAC,CAGvC;IAED;;;;;;;;;;;OAWG;IACH,IAAI,iBAAiB,IAAI,GAAG,CAAC,MAAM,CAAC,CAEnC;IAED;;;;;;;;;;;;OAYG;IACH,IAAI,eAAe,IAAI,GAAG,CAAC,MAAM,CAAC,CAEjC;IAED;;OAEG;IACH,IAAI,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EAExC;IAEc,SAAS,CACtB,OAAO,EAAE,SAAS,CAAC,OAAO,EAC1B,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,IAAI,CAAC;CAOjB;AAED;;;;;GAKG;yBACa,OAAO,aAAa,KAAG,aAAa;AAApD,wBAAgF;AAGhF,OAAO,EAAE,aAAa,EAAE,CAAC"}
|