is-antibot 2.0.10 → 2.1.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 CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "is-antibot",
3
3
  "description": "Detect antibot protection from 30+ providers — Cloudflare, Akamai, DataDome, PerimeterX, Kasada, Imperva, reCAPTCHA, hCaptcha, Turnstile, and more.",
4
4
  "homepage": "https://antibot.microlink.io/",
5
- "version": "2.0.10",
5
+ "version": "2.1.1",
6
6
  "exports": {
7
7
  ".": "./src/index.js",
8
8
  "./providers.json": "./src/providers.json",
@@ -0,0 +1,51 @@
1
+ {
2
+ "log": {
3
+ "version": "1.2",
4
+ "creator": {
5
+ "name": "curl+node",
6
+ "version": "v24.16.0"
7
+ },
8
+ "entries": [
9
+ {
10
+ "request": {
11
+ "method": "GET",
12
+ "url": "https://img1.doubanio.com/icon/ul1000001-30.jpg"
13
+ },
14
+ "response": {
15
+ "status": 418,
16
+ "headers": [
17
+ {
18
+ "name": "date",
19
+ "value": "Fri, 12 Jun 2026 17:42:13 GMT"
20
+ },
21
+ {
22
+ "name": "content-type",
23
+ "value": "image/jpeg"
24
+ },
25
+ {
26
+ "name": "content-length",
27
+ "value": "13"
28
+ },
29
+ {
30
+ "name": "connection",
31
+ "value": "keep-alive"
32
+ },
33
+ {
34
+ "name": "x-cache-status",
35
+ "value": "MISS"
36
+ },
37
+ {
38
+ "name": "server",
39
+ "value": "marco/3.2"
40
+ }
41
+ ],
42
+ "content": {
43
+ "size": 13,
44
+ "mimeType": "image/jpeg",
45
+ "text": "cdn error 001"
46
+ }
47
+ }
48
+ }
49
+ ]
50
+ }
51
+ }
@@ -0,0 +1,91 @@
1
+ {
2
+ "log": {
3
+ "version": "1.2",
4
+ "creator": {
5
+ "name": "curl+node",
6
+ "version": "v24.16.0"
7
+ },
8
+ "entries": [
9
+ {
10
+ "request": {
11
+ "method": "GET",
12
+ "url": "https://dribbble.com/omidnikrah"
13
+ },
14
+ "response": {
15
+ "status": 403,
16
+ "headers": [
17
+ {
18
+ "name": "content-type",
19
+ "value": "text/plain"
20
+ },
21
+ {
22
+ "name": "content-length",
23
+ "value": "10"
24
+ },
25
+ {
26
+ "name": "connection",
27
+ "value": "keep-alive"
28
+ },
29
+ {
30
+ "name": "date",
31
+ "value": "Fri, 12 Jun 2026 17:42:12 GMT"
32
+ },
33
+ {
34
+ "name": "x-runtime",
35
+ "value": "0.110796"
36
+ },
37
+ {
38
+ "name": "server",
39
+ "value": "nginx"
40
+ },
41
+ {
42
+ "name": "x-request-id",
43
+ "value": "dcdbb866-65fb-4310-a262-1de3c31803d2"
44
+ },
45
+ {
46
+ "name": "x-cache",
47
+ "value": "Error from cloudfront"
48
+ },
49
+ {
50
+ "name": "via",
51
+ "value": "1.1 f97045cd1d5b0bf2360d2e427fb0d2ae.cloudfront.net (CloudFront)"
52
+ },
53
+ {
54
+ "name": "x-amz-cf-pop",
55
+ "value": "CDG50-P5"
56
+ },
57
+ {
58
+ "name": "x-amz-cf-id",
59
+ "value": "0zTURQ1zPnKKWYtAvVR7-4BYBOubboCnptA0JFHOEqz8eY-YE9wtGQ=="
60
+ },
61
+ {
62
+ "name": "x-xss-protection",
63
+ "value": "1; mode=block"
64
+ },
65
+ {
66
+ "name": "x-frame-options",
67
+ "value": "SAMEORIGIN"
68
+ },
69
+ {
70
+ "name": "referrer-policy",
71
+ "value": "strict-origin-when-cross-origin"
72
+ },
73
+ {
74
+ "name": "x-content-type-options",
75
+ "value": "nosniff"
76
+ },
77
+ {
78
+ "name": "strict-transport-security",
79
+ "value": "max-age=31536000; includeSubDomains; preload"
80
+ }
81
+ ],
82
+ "content": {
83
+ "size": 10,
84
+ "mimeType": "text/plain",
85
+ "text": "Forbidden\n"
86
+ }
87
+ }
88
+ }
89
+ ]
90
+ }
91
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "log": {
3
+ "version": "1.2",
4
+ "creator": {
5
+ "name": "curl+node",
6
+ "version": "v24.16.0"
7
+ },
8
+ "entries": [
9
+ {
10
+ "request": {
11
+ "method": "GET",
12
+ "url": "https://m.weibo.cn/u/2803301701"
13
+ },
14
+ "response": {
15
+ "status": 200,
16
+ "headers": [
17
+ {
18
+ "name": "content-type",
19
+ "value": "text/html"
20
+ },
21
+ {
22
+ "name": "transfer-encoding",
23
+ "value": "chunked"
24
+ },
25
+ {
26
+ "name": "connection",
27
+ "value": "keep-alive"
28
+ },
29
+ {
30
+ "name": "date",
31
+ "value": "Fri, 12 Jun 2026 17:42:11 GMT"
32
+ },
33
+ {
34
+ "name": "vary",
35
+ "value": "Accept-Encoding"
36
+ },
37
+ {
38
+ "name": "cache-control",
39
+ "value": "no-cache, must-revalidate"
40
+ },
41
+ {
42
+ "name": "expires",
43
+ "value": "Sat, 26 Jul 1997 05:00:00 GMT"
44
+ },
45
+ {
46
+ "name": "pragma",
47
+ "value": "no-cache, no-cache"
48
+ },
49
+ {
50
+ "name": "content-encoding",
51
+ "value": "gzip"
52
+ },
53
+ {
54
+ "name": "content-security-policy",
55
+ "value": "upgrade-insecure-requests"
56
+ },
57
+ {
58
+ "name": "strict-transport-security",
59
+ "value": "max-age=31536000; includeSubDomains"
60
+ },
61
+ {
62
+ "name": "server",
63
+ "value": "APISIX/3.14.1"
64
+ },
65
+ {
66
+ "name": "alb-x-request-id",
67
+ "value": "49996fcb-d5b6-405d-a546-8fa446788955"
68
+ }
69
+ ],
70
+ "content": {
71
+ "size": 9092,
72
+ "mimeType": "text/html",
73
+ "text": "<!DOCTYPE html>\n<html>\n<head>\n <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\"/>\n <title>Sina Visitor System</title>\n</head>\n<body>\n<span id=\"message\"></span>\n<script type=\"text/javascript\" src=\"/js/visitor/mini_original.js?v=20161116\"></script>\n<script src=\"https://passport.sinaimg.cn/js/fp/1.2.1.umd.js\"></script>\n<script type=\"text/javascript\">\n window.use_fp = \"0\" == \"1\"; // 是否采集设备指纹。\n var url = url || {};\n (function () {\n this.l = function (u, c) {\n try {\n var s = document.createElement(\"script\");\n s.type = \"text/javascript\";\n s[document.all ? \"onreadystatechange\" : \"onload\"] = function () {\n if (document.all && this.readyState != \"loaded\" && this.readyState != \"complete\") {\n return\n }\n this[document.all ? \"onreadystatechange\" : \"onload\"] = null;\n this.parentNode.removeChild(this);\n if (c) {\n c()\n }\n };\n s.src = u;\n document.getElementsByTagName(\"head\")[0].appendChild(s)\n } catch (e) {\n }\n };\n }).call(url);\n\n var visitor_origin = function () {\n try {\n var need_restore = \"0\" == \"1\"; // 是否走恢复身份流程。\n\n // 如果需要走恢复身份流程,尝试从 cookie 获取用户身份。\n if (!need_restore || !Store.CookieHelper.get(\"SRF\")) {\n\n // 若获取失败走创建访客流程。\n // 流程执行时间过长(超过 3s),则认为出错。\n var error_timeout = window.setTimeout(\"error_back()\", 5000);\n\n tid.get(function (tid, where, confidence) {\n // 取指纹顺利完成,清除出错 timeout 。\n window.clearTimeout(error_timeout);\n incarnate(tid, where, confidence);\n });\n } else {\n // 用户身份存在,尝试恢复用户身份。\n restore();\n }\n } catch (e) {\n // 出错。\n error_back();\n }\n };\n\n var visitor_gray = function () {\n var from = \"weibo\";\n var return_url = \"https://m.weibo.cn/u/2803301701\";\n var request_id = \"c2469d596c7c3760ada78cc6c2e22ce2\";\n var webdriver = navigator.webdriver;\n\n // 先生成 rid,再发送请求\n generateRid(function(rid) {\n Store.DB.get(\"tid\", function (v) {\n if (!v) {\n v = \"\";\n }\n ufp.util.postData('https://' + window.location.host + '/visitor/genvisitor2', 'cb=visitor_gray_callback&ver=20250916&request_id='+request_id+'&tid=' + v + '&from=' + from + '&webdriver=' + webdriver + '&rid=' + rid + '&return_url=' + return_url, function (res) {\n if (res) {\n eval(res);\n }\n });\n });\n });\n }\n\n // 生成 rid 的独立方法\n var generateRid = function(callback) {\n var rid = Date.now();\n var detector = window.wbBotDetector;\n if (!detector) {\n callback(rid);\n return;\n }\n try{\n detector.load({ \"from\": \"pc-visitor\" });\n detector.get({useCache:false}).then(function (result) {\n if (result.rid) {\n rid = result.rid;\n }else{\n rid = \"error: empty\";\n }\n callback(rid);\n }).catch(function (error) {\n callback(\"get-error:\"+error);\n });\n }catch (e){\n callback(\"error:\" + e.message);\n }\n };\n\n // 流程入口。\n wload(function () {\n visitor_gray();\n });\n\n // “返回” 回调函数。\n var return_back = function (response) {\n\n if (response[\"retcode\"] == 20000000) {\n back();\n } else {\n // 出错。\n error_back(response[\"msg\"]);\n }\n };\n\n // 跳转回初始地址。\n var back = function () {\n\n var url = \"https://m.weibo.cn/u/2803301701\";\n if (url != \"none\") {\n window.location.replace(url);\n }\n };\n\n // 跨域广播。\n var cross_domain = function (response) {\n\n var from = \"weibo\";\n var entry = \"sinawap\";\n if (response[\"retcode\"] == 20000000) {\n\n var crossdomain_host = \"none\";\n if (crossdomain_host != \"none\") {\n\n var cross_domain_intr = window.location.protocol + \"//\" + crossdomain_host + \"/visitor/visitor?a=crossdomain&cb=return_back&s=\" +\n encodeURIComponent(response[\"data\"][\"sub\"]) + \"&sp=\" + encodeURIComponent(response[\"data\"][\"subp\"]) + \"&from=\" + from + \"&_rand=\" + Math.random() + \"&entry=\" + entry;\n url.l(cross_domain_intr);\n } else {\n\n back();\n }\n } else {\n\n // 出错。\n error_back(response[\"msg\"]);\n }\n };\n\n // 跨域广播。\n var cross_domain2 = function (response) {\n\n var from = \"weibo\";\n var entry = \"sinawap\";\n if (response[\"retcode\"] == 20000000) {\n\n var crossdomain_host = \"none\";\n if (crossdomain_host != \"none\") {\n\n var cross_domain_intr = window.location.protocol + \"//\" + crossdomain_host + \"/visitor/visitor?a=crossdomain&s=\" +\n encodeURIComponent(response[\"data\"][\"sub\"]) + \"&sp=\" + encodeURIComponent(response[\"data\"][\"subp\"]) + \"&from=\" + from + \"&_rand=\" + Math.random() + \"&entry=\" + entry+\"&url=\" + encodeURIComponent(\"https://m.weibo.cn/u/2803301701\");\n window.location.replace(cross_domain_intr);\n } else {\n back();\n }\n } else {\n\n // 出错。\n error_back(response[\"msg\"]);\n }\n };\n\n // 为用户赋予访客身份 。\n var incarnate = function (tid, where, conficence) {\n\n var gen_conf = \"\";\n var from = \"weibo\";\n var incarnate_intr = \"https://\" + window.location.host + \"/visitor/visitor?a=incarnate&t=\" +\n encodeURIComponent(tid) + \"&w=\" + encodeURIComponent(where) + \"&c=\" + encodeURIComponent(conficence) +\n \"&gc=\" + encodeURIComponent(gen_conf) + \"&cb=cross_domain&from=\" + from + \"&_rand=\" + Math.random();\n url.l(incarnate_intr);\n };\n\n // 恢复用户丢失的身份。\n var restore = function () {\n\n var from = \"weibo\";\n var restore_intr = \"https://\" + window.location.host +\n \"/visitor/visitor?a=restore&cb=restore_back&from=\" + from + \"&_rand=\" + Math.random();\n\n url.l(restore_intr);\n };\n\n // 跨域恢复丢失的身份。\n var restore_back = function (response) {\n\n // 身份恢复成功走广播流程,否则走创建访客流程。\n if (response[\"retcode\"] == 20000000) {\n\n var url = \"https://m.weibo.cn/u/2803301701\";\n var alt = response[\"data\"][\"alt\"];\n if (alt != \"\") {\n requrl = (url == \"none\") ? \"\" : \"&url=\" + encodeURIComponent(url);\n var params = \"entry=sso&source=visitor_restore&type=3&alt=\" + encodeURIComponent(alt) + requrl;\n window.location.replace(\"https://passport.weibo.com/sso/v2/login?\" + params);\n } else {\n\n cross_domain(response);\n }\n } else if (response['retcode'] == 50111261 && isInIframe()) {\n //do nothing\n } else {\n\n tid.get(function (tid, where, confidence) {\n incarnate(tid, where, confidence);\n });\n }\n };\n\n // 出错情况返回登录页。\n var error_back = function (msg) {\n\n var url = \"https://m.weibo.cn/u/2803301701\";\n var clientType = \"mobile\";\n if (url != \"none\") {\n\n if (url.indexOf(\"ssovie4c55=0\") === -1) {\n url += (((url.indexOf(\"?\") === -1) ? \"?\" : \"&\") + \"ssovie4c55=0\");\n }\n if (clientType == \"mobile\") {\n window.location.replace(\"https://passport.weibo.cn/signin/login?r=\" + url);\n } else {\n window.location.replace(\"https://weibo.com/login.php\");\n }\n } else {\n\n if (document.getElementById(\"message\")) {\n document.getElementById(\"message\").innerHTML = \"Error occurred\" + (msg ? (\": \" + msg) : \".\");\n }\n }\n };\n\n var visitor_gray_callback = function (response) {\n if (response[\"retcode\"] === 20000000) {\n var tid = response[\"data\"][\"tid\"];\n Store.DB.set('tid', tid);\n\n var alt = response[\"data\"][\"alt\"];\n if (alt !== \"\") {\n var url = \"https://m.weibo.cn/u/2803301701\";\n requrl = (url === \"none\") ? \"\" : \"&url=\" + encodeURIComponent(url);\n var params = \"entry=sso&source=visitor_restore&type=3&alt=\" + encodeURIComponent(alt) + requrl;\n window.location.replace(\"https://passport.weibo.com/sso/v2/login?\" + params);\n } else {\n cross_domain2(response)\n }\n }\n };\n\n var isInIframe = function () {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n };\n\n</script>\n</body>\n</html>"
74
+ }
75
+ }
76
+ }
77
+ ]
78
+ }
79
+ }
@@ -411,6 +411,7 @@
411
411
  },
412
412
  {
413
413
  "type": "html",
414
+ "statusCodes": [403, 429, 503],
414
415
  "rules": [
415
416
  {
416
417
  "contains": "g-recaptcha"
@@ -638,6 +639,9 @@
638
639
  {
639
640
  "regex": "blocked by network security\\.",
640
641
  "flags": "i"
642
+ },
643
+ {
644
+ "contains": "Please wait for verification"
641
645
  }
642
646
  ]
643
647
  }
@@ -798,6 +802,51 @@
798
802
  ]
799
803
  }
800
804
  ]
805
+ },
806
+ {
807
+ "name": "weibo",
808
+ "description": "Sina Visitor System gate served to non-China/bot clients before hydrating the page.",
809
+ "detections": [
810
+ {
811
+ "type": "html",
812
+ "domainWithoutSuffix": "weibo",
813
+ "rules": [
814
+ {
815
+ "contains": "Sina Visitor System"
816
+ }
817
+ ]
818
+ }
819
+ ]
820
+ },
821
+ {
822
+ "name": "dribbble",
823
+ "description": "Dribbble answers 403 Forbidden to crawler/bot user agents.",
824
+ "detections": [
825
+ {
826
+ "type": "status_code",
827
+ "domain": "dribbble.com",
828
+ "rules": [
829
+ {
830
+ "status": 403
831
+ }
832
+ ]
833
+ }
834
+ ]
835
+ },
836
+ {
837
+ "name": "douban",
838
+ "description": "Douban's image CDN answers 418 to requests without a matching Referer.",
839
+ "detections": [
840
+ {
841
+ "type": "status_code",
842
+ "domain": "doubanio.com",
843
+ "rules": [
844
+ {
845
+ "status": 418
846
+ }
847
+ ]
848
+ }
849
+ ]
801
850
  }
802
851
  ]
803
852
  }