Documentation
¶
Overview ¶
Package detect recognises bot-challenge and WAF block pages.
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var Signatures = []Signature{ { Vendor: "Cloudflare", Header: func(h http.Header) bool { return strings.EqualFold(h.Get("cf-mitigated"), "challenge") }, Body: regexp.MustCompile(`(?i)(__cf_chl_|cf-browser-verification|cf_chl_opt|<title>Just a moment\.\.\.</title>|Attention Required! \| Cloudflare)`), Embedded: regexp.MustCompile(`(?i)/cdn-cgi/challenge-platform/`), }, { Vendor: "Akamai", Body: regexp.MustCompile(`(?i)(/_sec/verify\?provider=interstitial|triggerInterstitialChallenge|[?&]bm-verify=)`), }, { Vendor: "Akamai", Statuses: []int{403}, Body: regexp.MustCompile(`(?is)Access Denied.*(Reference(\s| )*(#|#)\d+(\.|.)|errors(\.|.)edgesuite(\.|.)net)`), }, { Vendor: "DataDome", Header: func(h http.Header) bool { return h.Get("X-DataDome") != "" && h.Get("X-DD-B") != "" }, Body: regexp.MustCompile(`(?i)(geo\.captcha-delivery\.com|ct\.captcha-delivery\.com|dd=\{'rt':'c')`), }, { Vendor: "PerimeterX", Statuses: []int{403, 429}, Body: regexp.MustCompile(`(?i)(/_px[a-z0-9]*/|px-captcha|_pxAppId|window\._pxUuid|Press & Hold|Press & Hold)`), }, { Vendor: "Imperva", Body: regexp.MustCompile(`(?i)(Incapsula incident ID|Request unsuccessful\. Incapsula)`), Embedded: regexp.MustCompile(`(?i)_Incapsula_Resource`), }, { Vendor: "Kasada", Header: func(h http.Header) bool { return h.Get("X-Kpsdk-Ct") != "" || h.Get("X-Kpsdk-C") != "" }, Embedded: regexp.MustCompile(`(?i)(/149e9513-01fa-4fb0-aad4-566afd725d1b/|KPSDK\.configure)`), }, { Vendor: "AWS WAF", Header: func(h http.Header) bool { return strings.EqualFold(h.Get("X-Amzn-Waf-Action"), "challenge") || strings.EqualFold(h.Get("X-Amzn-Waf-Action"), "captcha") }, Embedded: regexp.MustCompile(`(?i)(awswaf\.com/[^"']*challenge\.js|AwsWafIntegration)`), }, { Vendor: "Sucuri", Statuses: []int{403, 503}, Body: regexp.MustCompile(`(?i)(Sucuri WebSite Firewall|sucuri\.net/privacy-policy|cloudproxy@sucuri)`), }, { Vendor: "CAPTCHA", Statuses: []int{401, 403, 405, 429, 503}, Body: regexp.MustCompile(`(?i)(class=["'][^"']*g-recaptcha|class=["'][^"']*h-captcha|class=["'][^"']*cf-turnstile|data-sitekey=)`), }, }
Signatures is checked in order; the first match wins.
Functions ¶
Types ¶
type Signature ¶
type Signature struct {
Vendor string
// Statuses restricts Body matching to these status codes. Empty means any.
Statuses []int
// Header reports whether response headers alone identify the vendor.
Header func(h http.Header) bool
// Body matches markers that only appear on the challenge or block page.
Body *regexp.Regexp
// Embedded matches scripts the vendor also injects into healthy pages
// (Cloudflare's challenge platform, AWS WAF's challenge.js). They only
// count when the response is not a success, or a healthy page that
// happens to load the script would be reported as challenged.
Embedded *regexp.Regexp
}
Signature describes how one vendor's challenge or block page looks.
A response matches when the vendor's header check passes, when Body (a marker only a challenge or block page contains) matches under the status filter, or when Embedded matches on a response that is not a success.
Click to show internal directories.
Click to hide internal directories.