is-antibot 1.6.2 → 1.7.1
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/package.json +29 -4
- package/src/index.js +14 -1
- package/README.md +0 -107
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "is-antibot",
|
|
3
|
-
"description": "
|
|
4
|
-
"homepage": "https://
|
|
5
|
-
"version": "1.
|
|
3
|
+
"description": "Detect antibot protection from 30+ providers — Cloudflare, Akamai, DataDome, PerimeterX, Kasada, Imperva, reCAPTCHA, hCaptcha, Turnstile, and more.",
|
|
4
|
+
"homepage": "https://antibot.microlink.io/",
|
|
5
|
+
"version": "1.7.1",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./src/index.js"
|
|
8
8
|
},
|
|
@@ -31,14 +31,18 @@
|
|
|
31
31
|
"keywords": [
|
|
32
32
|
"akamai",
|
|
33
33
|
"antibot",
|
|
34
|
+
"anubis",
|
|
34
35
|
"arkose",
|
|
35
36
|
"aws-waf",
|
|
36
37
|
"bot",
|
|
38
|
+
"bot-detection",
|
|
39
|
+
"bot-protection",
|
|
37
40
|
"captcha",
|
|
38
41
|
"challenge",
|
|
39
42
|
"cloudflare",
|
|
40
43
|
"datadome",
|
|
41
44
|
"detection",
|
|
45
|
+
"friendly-captcha",
|
|
42
46
|
"funcaptcha",
|
|
43
47
|
"geetest",
|
|
44
48
|
"hcaptcha",
|
|
@@ -46,13 +50,16 @@
|
|
|
46
50
|
"incapsula",
|
|
47
51
|
"kasada",
|
|
48
52
|
"perimeterx",
|
|
53
|
+
"reblaze",
|
|
49
54
|
"recaptcha",
|
|
50
55
|
"scraper",
|
|
51
56
|
"scraping",
|
|
52
57
|
"shapesecurity",
|
|
58
|
+
"sucuri",
|
|
53
59
|
"turnstile",
|
|
54
60
|
"vercel",
|
|
55
|
-
"waf"
|
|
61
|
+
"waf",
|
|
62
|
+
"web-scraping"
|
|
56
63
|
],
|
|
57
64
|
"dependencies": {
|
|
58
65
|
"@metascraper/helpers": "~5.50.0",
|
|
@@ -64,14 +71,24 @@
|
|
|
64
71
|
"@commitlint/config-conventional": "latest",
|
|
65
72
|
"@ksmithut/prettier-standard": "latest",
|
|
66
73
|
"ava": "latest",
|
|
74
|
+
"browser-sync": "latest",
|
|
67
75
|
"c8": "latest",
|
|
68
76
|
"ci-publish": "latest",
|
|
77
|
+
"concurrently": "latest",
|
|
69
78
|
"conventional-changelog-cli": "latest",
|
|
79
|
+
"cssnano": "latest",
|
|
80
|
+
"cssnano-preset-advanced": "latest",
|
|
70
81
|
"finepack": "latest",
|
|
71
82
|
"git-authors-cli": "latest",
|
|
72
83
|
"github-generate-release": "latest",
|
|
73
84
|
"got": "11",
|
|
85
|
+
"gulp": "5",
|
|
86
|
+
"gulp-concat": "latest",
|
|
87
|
+
"gulp-postcss": "latest",
|
|
88
|
+
"gulp-uglify": "latest",
|
|
74
89
|
"nano-staged": "latest",
|
|
90
|
+
"postcss": "latest",
|
|
91
|
+
"postcss-focus": "latest",
|
|
75
92
|
"simple-git-hooks": "latest",
|
|
76
93
|
"standard": "latest",
|
|
77
94
|
"standard-version": "latest"
|
|
@@ -83,9 +100,12 @@
|
|
|
83
100
|
"src"
|
|
84
101
|
],
|
|
85
102
|
"scripts": {
|
|
103
|
+
"build": "gulp build",
|
|
86
104
|
"clean": "rm -rf node_modules",
|
|
87
105
|
"contributors": "(npx git-authors-cli && npx finepack && git add package.json && git commit -m 'build: contributors' --no-verify) || true",
|
|
88
106
|
"coverage": "c8 report --reporter=text-lcov > coverage/lcov.info",
|
|
107
|
+
"dev": "concurrently \"gulp\" \"npm run dev:server\"",
|
|
108
|
+
"dev:server": "browser-sync start --server docs --files \"docs/index.html, docs/README.md, docs/static/**/*.(css|js)\"",
|
|
89
109
|
"lint": "standard",
|
|
90
110
|
"postrelease": "npm run release:tags && npm run release:github && (ci-publish || npm publish --access=public)",
|
|
91
111
|
"pretest": "npm run lint",
|
|
@@ -127,5 +147,10 @@
|
|
|
127
147
|
"simple-git-hooks": {
|
|
128
148
|
"commit-msg": "npx commitlint --edit",
|
|
129
149
|
"pre-commit": "npx nano-staged"
|
|
150
|
+
},
|
|
151
|
+
"standard": {
|
|
152
|
+
"ignore": [
|
|
153
|
+
"docs/static/main.min.js"
|
|
154
|
+
]
|
|
130
155
|
}
|
|
131
156
|
}
|
package/src/index.js
CHANGED
|
@@ -77,7 +77,7 @@ const detect = ({ headers = {}, html = '', url = '', statusCode } = {}) => {
|
|
|
77
77
|
const byStatusCode = provider =>
|
|
78
78
|
createResult(true, provider, DETECTION.STATUS_CODE)
|
|
79
79
|
|
|
80
|
-
//
|
|
80
|
+
// Cloudflare: Check for cf-mitigated header with 'challenge' value
|
|
81
81
|
// Official docs: https://developers.cloudflare.com/cloudflare-challenges/challenge-types/challenge-pages/detect-response/
|
|
82
82
|
if (getHeader('cf-mitigated') === 'challenge') {
|
|
83
83
|
return byHeaders('cloudflare')
|
|
@@ -413,6 +413,19 @@ const detect = ({ headers = {}, html = '', url = '', statusCode } = {}) => {
|
|
|
413
413
|
return byHtml('youtube')
|
|
414
414
|
}
|
|
415
415
|
|
|
416
|
+
// Anubis (Techaro BotStopper): challenge pages always contain the JSON script block
|
|
417
|
+
// `<script id="anubis_challenge" type="application/json">` (hardcoded in web/index.templ)
|
|
418
|
+
// and asset/API URLs under the Go constant `StaticPath = "/.within.website/x/cmd/anubis/"`.
|
|
419
|
+
// Source: https://github.com/TecharoHQ/anubis
|
|
420
|
+
if (
|
|
421
|
+
hasAnyHtml([
|
|
422
|
+
/<script id="anubis_challenge"/,
|
|
423
|
+
'/.within.website/x/cmd/anubis/'
|
|
424
|
+
])
|
|
425
|
+
) {
|
|
426
|
+
return byHtml('anubis')
|
|
427
|
+
}
|
|
428
|
+
|
|
416
429
|
// AWS WAF: Check for x-amzn-waf-action or x-amzn-requestid headers
|
|
417
430
|
// Reference: https://github.com/scrapfly/Antibot-Detector/blob/main/detectors/antibot/detect-aws-waf.json
|
|
418
431
|
if (hasAnyHeader(['x-amzn-waf-action', 'x-amzn-requestid'])) {
|
package/README.md
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
<picture>
|
|
2
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/microlinkhq/cdn/raw/master/dist/logo/banner-dark.png">
|
|
3
|
-
<img alt="microlink cdn" src="https://github.com/microlinkhq/cdn/raw/master/dist/logo/banner.png" align="center">
|
|
4
|
-
</picture>
|
|
5
|
-
|
|
6
|
-

|
|
7
|
-
[](https://coveralls.io/github/microlinkhq/is-antibot)
|
|
8
|
-
[](https://www.npmjs.org/package/is-antibot)
|
|
9
|
-
|
|
10
|
-
> Identify if a response is an antibot challenge from CloudFlare, Akamai, DataDome, Vercel, and more.
|
|
11
|
-
|
|
12
|
-
## Supported Providers
|
|
13
|
-
|
|
14
|
-
### Anti-Bot Systems
|
|
15
|
-
|
|
16
|
-
- **CloudFlare** - Bot management and challenge pages
|
|
17
|
-
- **Vercel** - Attack mode protection
|
|
18
|
-
- **Akamai** - Bot Manager and Web Application Protector
|
|
19
|
-
- **DataDome** - Bot protection with CAPTCHA challenges
|
|
20
|
-
- **PerimeterX** - Behavioral bot detection
|
|
21
|
-
- **Shape Security** - Enterprise bot management
|
|
22
|
-
- **Kasada** - Advanced bot mitigation
|
|
23
|
-
- **Imperva/Incapsula** - Web application firewall
|
|
24
|
-
- **AWS WAF** - Amazon Web Services Web Application Firewall
|
|
25
|
-
- **Reblaze** - Cloud-based web security platform
|
|
26
|
-
- **Cheq** - Bot detection and prevention
|
|
27
|
-
- **Sucuri** - Website security platform and WAF
|
|
28
|
-
- **ThreatMetrix** - LexisNexis fraud prevention and device fingerprinting
|
|
29
|
-
- **Meetrics** - User authenticity verification
|
|
30
|
-
- **Ocule** - Bot detection with advanced obfuscation
|
|
31
|
-
- **YouTube** - BotGuard attestation and abuse detection
|
|
32
|
-
- **LinkedIn** - Bot filter protection
|
|
33
|
-
- **Reddit** - Network security challenge-page detection
|
|
34
|
-
|
|
35
|
-
### CAPTCHA Providers
|
|
36
|
-
|
|
37
|
-
- **reCAPTCHA** - Google's CAPTCHA service (v2 and v3)
|
|
38
|
-
- **hCaptcha** - Privacy-focused CAPTCHA alternative
|
|
39
|
-
- **FunCaptcha** - Arkose Labs interactive challenges
|
|
40
|
-
- **GeeTest** - AI-powered CAPTCHA
|
|
41
|
-
- **Cloudflare Turnstile** - Privacy-preserving CAPTCHA alternative
|
|
42
|
-
- **Friendly Captcha** - GDPR-compliant privacy-first CAPTCHA
|
|
43
|
-
- **Captcha.eu** - European GDPR-compliant CAPTCHA service
|
|
44
|
-
- **QCloud Captcha** - Tencent Cloud CAPTCHA service
|
|
45
|
-
- **AliExpress CAPTCHA** - AliExpress x5sec security challenge
|
|
46
|
-
|
|
47
|
-
## Why
|
|
48
|
-
|
|
49
|
-
Websites receiving massive quantities of traffic throughout the day, like LinkedIn, Reddit, Instagram, or YouTube, have sophisticated antibot systems to prevent automated access.
|
|
50
|
-
|
|
51
|
-
When you try to fetch the HTML of these sites without the right tools, you often hit a 403 Forbidden, 429 Too Many Requests, or a "Please prove you're human" challenge, leaving you with a response that contains no useful data.
|
|
52
|
-
|
|
53
|
-
**is-antibot** is a lightweight, vendor-agnostic JavaScript library that identifies when a response is actually an antibot challenge, helping you understand when and why your request was blocked.
|
|
54
|
-
|
|
55
|
-
## Install
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
$ npm install is-antibot --save
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Usage
|
|
62
|
-
|
|
63
|
-
Just pass `headers`, `html`, `url`, and `statusCode` from any HTTP response:
|
|
64
|
-
|
|
65
|
-
```js
|
|
66
|
-
const isAntibot = require('is-antibot')
|
|
67
|
-
|
|
68
|
-
const response = await fetch('https://www.linkedin.com/in/kikobeats/')
|
|
69
|
-
const html = await response.text()
|
|
70
|
-
|
|
71
|
-
const { detected, provider, detection } = isAntibot({
|
|
72
|
-
headers: response.headers,
|
|
73
|
-
statusCode: response.status,
|
|
74
|
-
html,
|
|
75
|
-
url: response.url
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
if (detected) {
|
|
79
|
-
console.log(`Antibot detected: ${provider} via ${detection}`)
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
It also works with [got](https://github.com/sindresorhus/got) or any library where `body` is a string:
|
|
84
|
-
|
|
85
|
-
```js
|
|
86
|
-
const response = await got('https://www.linkedin.com/in/kikobeats/')
|
|
87
|
-
.catch(error => errorresponse)
|
|
88
|
-
|
|
89
|
-
const { detected, provider, detection } = isAntibot(response)
|
|
90
|
-
|
|
91
|
-
if (detected) {
|
|
92
|
-
console.log(`Antibot detected: ${provider} via ${detection}`)
|
|
93
|
-
}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
The library returns an object with the following properties:
|
|
97
|
-
|
|
98
|
-
- `detected` (boolean): Whether an antibot challenge was detected
|
|
99
|
-
- `provider` (string|null): The name of the detected provider (e.g., 'cloudflare', 'recaptcha')
|
|
100
|
-
- `detection` (string|null): Where the signal came from: `'headers'`, `'cookies'`, `'html'`, `'url'`, or `'statusCode'`
|
|
101
|
-
|
|
102
|
-
## License
|
|
103
|
-
|
|
104
|
-
**is-antibot** © [microlink.io](https://microlink.io), released under the [MIT](https://github.com/microlinkhq/is-antibot/blob/master/LICENSE.md) License.<br>
|
|
105
|
-
Authored and maintained by [microlink.io](https://microlink.io) with help from [contributors](https://github.com/microlinkhq/is-antibot/contributors).
|
|
106
|
-
|
|
107
|
-
> [microlink.io](https://microlink.io) · GitHub [microlink.io](https://github.com/microlinkhq) · X [@microlinkhq](https://x.com/microlinkhq)
|