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.
Files changed (3) hide show
  1. package/package.json +29 -4
  2. package/src/index.js +14 -1
  3. package/README.md +0 -107
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "is-antibot",
3
- "description": "Identify if a response is an antibot challenge from CloudFlare, Akamai, DataDome, Vercel, PerimeterX, Shape Security, and more, including CAPTCHA providers like reCAPTCHA and hCaptcha.",
4
- "homepage": "https://github.com/microlinkhq/is-antibot",
5
- "version": "1.6.2",
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
- // CloudFlare: Check for cf-mitigated header with 'challenge' value
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
- ![Last version](https://img.shields.io/github/tag/microlinkhq/is-antibot.svg?style=flat-square)
7
- [![Coverage Status](https://img.shields.io/coveralls/microlinkhq/is-antibot.svg?style=flat-square)](https://coveralls.io/github/microlinkhq/is-antibot)
8
- [![NPM Status](https://img.shields.io/npm/dm/is-antibot.svg?style=flat-square)](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)