1"""Hand-written technology fingerprints for the Tech Stack & Email Provider Detector.
2
3This set was authored from scratch for this Actor (it is NOT derived from Wappalyzer /
4webappanalyzer data). Every rule is a plain regular expression matched against one kind
5of public signal:
6
7 script - the src URL of a <script> tag
8 link - the href of a <link> tag (stylesheets, preconnects, ...)
9 html - the raw HTML of the page (inline scripts, globals, markup)
10 meta - {meta-name: regex} matched against <meta name=... content=...>
11 header - {header-name: regex} matched against response header values
12 cookie - regex matched against Set-Cookie *names only* (values are never read)
13
14Each rule carries a confidence (0-100). Multiple hits for one technology are combined
15with a noisy-OR in detector.py. 'implies' adds technologies that are logically present
16(e.g. WooCommerce implies WordPress) at the implying technology's confidence.
17"""
18
19from __future__ import annotations
20
21
22CMS = "CMS"
23ECOMMERCE = "Ecommerce"
24ANALYTICS = "Analytics"
25TAG_MANAGER = "Tag manager"
26MARKETING = "Marketing automation"
27CRM = "CRM"
28CHAT = "Live chat / support"
29EMAIL_MARKETING = "Email marketing"
30PAYMENTS = "Payments"
31JS_FRAMEWORK = "JavaScript framework"
32JS_LIBRARY = "JavaScript library"
33CDN = "CDN"
34HOSTING = "Hosting / PaaS"
35WEB_SERVER = "Web server"
36AB_TESTING = "A/B testing"
37REVIEWS = "Reviews"
38FONTS = "Fonts"
39ADVERTISING = "Advertising pixel"
40
41ANALYTICS_CATEGORIES = {ANALYTICS, TAG_MANAGER, ADVERTISING}
42
43FINGERPRINTS: list[dict] = [
44
45 {
46 "name": "WordPress",
47 "category": CMS,
48 "script": [(r"/wp-(?:content|includes)/", 80)],
49 "link": [(r"/wp-(?:content|includes)/", 80), (r"/wp-json/", 70)],
50 "html": [(r"/wp-content/(?:themes|plugins|uploads)/", 80), (r"wp-emoji-release\.min\.js", 70)],
51 "meta": {"generator": [(r"^WordPress", 95)]},
52 "header": {"link": [(r"rel=\"?https://api\.w\.org/", 90)], "x-pingback": [(r"/xmlrpc\.php", 80)]},
53 "cookie": [(r"^wordpress_(?:logged_in|test_cookie|sec)", 60), (r"^wp-settings-", 60)],
54 },
55 {
56 "name": "Shopify",
57 "category": ECOMMERCE,
58 "script": [(r"cdn\.shopify\.com/", 85), (r"/cdn/shop/", 70)],
59 "link": [(r"cdn\.shopify\.com/", 80)],
60 "html": [(r"\bShopify\.shop\s*=", 95), (r"\bwindow\.Shopify\b", 80), (r"myshopify\.com", 60)],
61 "header": {"x-shopify-stage": [(r".", 95)], "x-shopid": [(r"^\d+$", 90)], "powered-by": [(r"(?i)shopify", 95)]},
62 "cookie": [(r"^_shopify_(?:y|s|sa_t|sa_p)$", 85), (r"^cart_currency$", 30)],
63 },
64 {
65 "name": "Wix",
66 "category": CMS,
67 "script": [(r"static\.parastorage\.com/", 85), (r"static\.wixstatic\.com/", 70)],
68 "html": [(r"static\.wixstatic\.com/", 75), (r"wix-thunderbolt|wixBiSession", 85)],
69 "meta": {"generator": [(r"^Wix\.com", 95)]},
70 "header": {"x-wix-request-id": [(r".", 95)]},
71 },
72 {
73 "name": "Squarespace",
74 "category": CMS,
75 "script": [(r"(?:static1|assets)\.squarespace\.com/", 85)],
76 "html": [(r"Static\.SQUARESPACE_CONTEXT", 95), (r"squarespace-cdn\.com", 70)],
77 "meta": {"generator": [(r"(?i)^Squarespace", 95)]},
78 "header": {"server": [(r"(?i)^Squarespace", 95)]},
79 },
80 {
81 "name": "Webflow",
82 "category": CMS,
83 "script": [(r"assets\.website-files\.com/|cdn\.prod\.website-files\.com/", 75), (r"webflow\.[0-9a-f.]*js", 80)],
84 "html": [(r"\bdata-wf-(?:page|site)=", 95)],
85 "meta": {"generator": [(r"^Webflow", 95)]},
86 },
87 {
88 "name": "Drupal",
89 "category": CMS,
90 "script": [(r"/(?:core/misc|misc)/drupal(?:\.init)?\.js", 85)],
91 "html": [(r"\bdrupalSettings\b|Drupal\.settings", 90), (r"/sites/(?:default|all)/files/", 60)],
92 "meta": {"generator": [(r"^Drupal", 95)]},
93 "header": {"x-generator": [(r"^Drupal", 95)], "x-drupal-cache": [(r".", 90)], "x-drupal-dynamic-cache": [(r".", 90)]},
94 },
95 {
96 "name": "Joomla",
97 "category": CMS,
98 "script": [(r"/media/(?:jui|system)/js/", 75)],
99 "html": [(r"Joomla!? - Open Source Content Management", 85)],
100 "meta": {"generator": [(r"^Joomla", 95)]},
101 },
102 {
103 "name": "Ghost",
104 "category": CMS,
105 "script": [(r"/ghost/(?:api|assets)/|ghost-(?:portal|search|sodo)", 75)],
106 "meta": {"generator": [(r"^Ghost", 95)]},
107 "header": {"x-ghost-cache-status": [(r".", 90)]},
108 },
109 {
110 "name": "HubSpot CMS",
111 "category": CMS,
112 "script": [(r"/hs/hsstatic/|static\.hsappstatic\.net/", 70)],
113 "meta": {"generator": [(r"^HubSpot", 95)]},
114 "header": {"x-hs-hub-id": [(r"^\d+$", 80)], "x-hs-cache-config": [(r".", 70)]},
115 "implies": ["HubSpot"],
116 },
117
118 {
119 "name": "WooCommerce",
120 "category": ECOMMERCE,
121 "script": [(r"/plugins/woocommerce/", 90), (r"wc-(?:add-to-cart|cart-fragments)(?:\.min)?\.js", 85)],
122 "link": [(r"/plugins/woocommerce/", 85)],
123 "html": [(r"\bwoocommerce-(?:page|no-js|cart|product)\b", 75), (r"wc_add_to_cart_params", 85)],
124 "meta": {"generator": [(r"^WooCommerce", 95)]},
125 "cookie": [(r"^woocommerce_(?:cart_hash|items_in_cart)$", 85), (r"^wp_woocommerce_session_", 85)],
126 "implies": ["WordPress"],
127 },
128 {
129 "name": "BigCommerce",
130 "category": ECOMMERCE,
131 "script": [(r"cdn\d*\.bigcommerce\.com/", 85)],
132 "html": [(r"\bBCData\s*=", 80), (r"stencil-utils", 60)],
133 "header": {"x-bc-storefront-request-id": [(r".", 90)]},
134 "cookie": [(r"^SHOP_SESSION_TOKEN$", 70)],
135 },
136 {
137 "name": "Magento",
138 "category": ECOMMERCE,
139 "script": [(r"/static/version\d+/frontend/", 85), (r"mage/(?:cookies|requirejs)", 80)],
140 "html": [(r"Magento_(?:Ui|Theme|Customer)", 85), (r"\bdata-mage-init=", 90)],
141 "header": {"x-magento-cache-debug": [(r".", 90)], "x-magento-tags": [(r".", 90)]},
142 "cookie": [(r"^(?:mage-cache-storage|mage-cache-sessid|form_key)$", 70)],
143 },
144 {
145 "name": "PrestaShop",
146 "category": ECOMMERCE,
147 "script": [(r"/themes/[^/]+/assets/js/(?:core|theme)\.js", 40), (r"/modules/ps_[a-z_]+/", 80)],
148 "html": [(r"\bprestashop\s*=\s*\{", 90), (r"var\s+prestashop\b", 90)],
149 "meta": {"generator": [(r"^PrestaShop", 95)]},
150 "header": {"powered-by": [(r"(?i)prestashop", 95)]},
151 "cookie": [(r"^PrestaShop-[0-9a-f]+$", 90)],
152 },
153
154 {
155 "name": "Google Analytics (GA4)",
156 "category": ANALYTICS,
157 "script": [(r"googletagmanager\.com/gtag/js\?id=G-", 95)],
158 "html": [(r"gtag\(\s*['\"]config['\"]\s*,\s*['\"]G-[A-Z0-9]+", 95)],
159 "cookie": [(r"^_ga_[A-Z0-9]+$", 85)],
160 },
161 {
162 "name": "Google Tag Manager",
163 "category": TAG_MANAGER,
164 "script": [(r"googletagmanager\.com/gtm\.js", 95)],
165 "html": [(r"googletagmanager\.com/(?:gtm\.js|ns\.html)\?id=GTM-", 95), (r"['\"]GTM-[A-Z0-9]{4,}['\"]", 70)],
166 },
167 {
168 "name": "Meta Pixel",
169 "category": ADVERTISING,
170 "script": [(r"connect\.facebook\.net/[a-z_A-Z]+/fbevents\.js", 95)],
171 "html": [(r"fbq\(\s*['\"]init['\"]", 90), (r"facebook\.com/tr\?id=", 85)],
172 "cookie": [(r"^_fbp$", 80)],
173 },
174 {
175 "name": "Hotjar",
176 "category": ANALYTICS,
177 "script": [(r"static\.hotjar\.com/", 95)],
178 "html": [(r"\bhjSiteSettings\b|_hjSettings\s*=", 90)],
179 "cookie": [(r"^_hj(?:SessionUser|Session|id)_", 80)],
180 },
181 {
182 "name": "Segment",
183 "category": ANALYTICS,
184 "script": [(r"cdn\.segment\.(?:com|io)/analytics\.js", 95)],
185 "html": [(r"analytics\.load\(\s*['\"][A-Za-z0-9]{10,}['\"]", 70), (r"cdn\.segment\.com", 80)],
186 "cookie": [(r"^ajs_anonymous_id$", 75)],
187 },
188 {
189 "name": "Mixpanel",
190 "category": ANALYTICS,
191 "script": [(r"cdn(?:4)?\.mxpnl\.com/|cdn\.mixpanel\.com/", 95)],
192 "html": [(r"mixpanel\.init\(", 90)],
193 "cookie": [(r"^mp_[0-9a-f]+_mixpanel$", 85)],
194 },
195 {
196 "name": "Plausible",
197 "category": ANALYTICS,
198 "script": [(r"plausible\.io/js/", 95)],
199 "html": [(r"data-domain=[^>]+plausible", 70), (r"window\.plausible\s*=", 85)],
200 },
201 {
202 "name": "TikTok Pixel",
203 "category": ADVERTISING,
204 "script": [(r"analytics\.tiktok\.com/i18n/pixel/", 95)],
205 "html": [(r"\bttq\.load\(", 90), (r"analytics\.tiktok\.com", 75)],
206 "cookie": [(r"^_ttp$", 70)],
207 },
208 {
209 "name": "LinkedIn Insight Tag",
210 "category": ADVERTISING,
211 "script": [(r"snap\.licdn\.com/li\.lms-analytics/insight", 95)],
212 "html": [(r"_linkedin_partner_id\s*=", 90), (r"px\.ads\.linkedin\.com/collect", 80)],
213 },
214
215 {
216 "name": "HubSpot",
217 "category": MARKETING,
218 "script": [(r"js(?:-[a-z0-9]+)?\.hs-scripts\.com/", 95), (r"js\.hs-analytics\.net/|js\.hsforms\.net/|js\.usemessages\.com/", 85)],
219 "html": [(r"\b_hsq\s*=|hbspt\.forms\.create", 85)],
220 "cookie": [(r"^(?:hubspotutk|__hstc|__hssc|__hssrc)$", 85)],
221 },
222 {
223 "name": "Klaviyo",
224 "category": EMAIL_MARKETING,
225 "script": [(r"static(?:-tracking)?\.klaviyo\.com/", 95)],
226 "html": [(r"\b_learnq\b|klaviyo\.init", 85)],
227 "cookie": [(r"^__kla_id$", 85)],
228 },
229 {
230 "name": "Mailchimp",
231 "category": EMAIL_MARKETING,
232 "script": [(r"chimpstatic\.com/mcjs-connected/", 95), (r"s3\.amazonaws\.com/downloads\.mailchimp\.com/", 85)],
233 "html": [(r"[a-z0-9-]+\.list-manage\.com/subscribe", 90), (r"\bmc-embedded-subscribe", 80)],
234 },
235 {
236 "name": "Intercom",
237 "category": CHAT,
238 "script": [(r"widget\.intercom\.io/widget/|js\.intercomcdn\.com/", 95)],
239 "html": [(r"window\.intercomSettings\s*=|Intercom\(\s*['\"]boot['\"]", 90)],
240 "cookie": [(r"^intercom-(?:id|session|device-id)-", 85)],
241 },
242 {
243 "name": "Drift",
244 "category": CHAT,
245 "script": [(r"js\.driftt\.com/", 95)],
246 "html": [(r"\bdrift\.load\(", 90), (r"js\.driftt\.com", 85)],
247 "cookie": [(r"^driftt_aid$", 80)],
248 },
249 {
250 "name": "Zendesk",
251 "category": CHAT,
252 "script": [(r"static\.zdassets\.com/ekr/snippet\.js", 95), (r"\.zendesk\.com/embeddable", 85)],
253 "html": [(r"\bze-snippet\b|zESettings\s*=", 85)],
254 },
255 {
256 "name": "Crisp",
257 "category": CHAT,
258 "script": [(r"client\.crisp\.chat/l\.js", 95)],
259 "html": [(r"CRISP_WEBSITE_ID\s*=", 95)],
260 },
261 {
262 "name": "Tawk.to",
263 "category": CHAT,
264 "script": [(r"embed\.tawk\.to/", 95)],
265 "html": [(r"embed\.tawk\.to/|Tawk_API\s*=", 90)],
266 },
267
268 {
269 "name": "Stripe",
270 "category": PAYMENTS,
271 "script": [(r"js\.stripe\.com/v\d", 95)],
272 "html": [(r"js\.stripe\.com|checkout\.stripe\.com|buy\.stripe\.com", 80), (r"\bStripe\(\s*['\"]pk_(?:live|test)_", 90)],
273 "cookie": [(r"^__stripe_(?:mid|sid)$", 85)],
274 },
275 {
276 "name": "PayPal",
277 "category": PAYMENTS,
278 "script": [(r"www\.paypal(?:objects)?\.com/(?:sdk/js|api/checkout|.*?/checkout\.js)", 95)],
279 "html": [(r"paypal\.Buttons\(|data-paypal-button|www\.paypal\.com/sdk/js", 85)],
280 },
281 {
282 "name": "Shop Pay",
283 "category": PAYMENTS,
284 "script": [(r"shop-js|shop\.app/(?:pay|checkouts)", 70)],
285 "html": [(r"<shop-pay-(?:button|wallet)|shopify-payment-button|data-shopify=\"payment-button\"", 85)],
286 "implies": ["Shopify"],
287 },
288
289 {
290 "name": "React",
291 "category": JS_FRAMEWORK,
292 "script": [(r"/react(?:-dom)?(?:\.production)?(?:\.min)?\.js", 85)],
293 "html": [(r"\bdata-reactroot\b|\bdata-reactid\b", 90), (r"__REACT_DEVTOOLS_GLOBAL_HOOK__|_reactRootContainer", 70)],
294 },
295 {
296 "name": "Next.js",
297 "category": JS_FRAMEWORK,
298 "script": [(r"/_next/static/", 95)],
299 "html": [(r"<script[^>]+id=\"__NEXT_DATA__\"", 95), (r"self\.__next_f\.push", 90)],
300 "header": {"x-powered-by": [(r"(?i)next\.js", 95)], "x-nextjs-cache": [(r".", 90)]},
301 "implies": ["React"],
302 },
303 {
304 "name": "Vue.js",
305 "category": JS_FRAMEWORK,
306 "script": [(r"/vue(?:@[\d.]+)?(?:/dist/vue)?(?:\.global|\.runtime)?(?:\.prod|\.min)?\.js", 85)],
307 "html": [(r"\bdata-v-[0-9a-f]{8}\b", 85), (r"\bdata-v-app\b|__VUE__", 85)],
308 },
309 {
310 "name": "Nuxt.js",
311 "category": JS_FRAMEWORK,
312 "script": [(r"/_nuxt/", 95)],
313 "html": [(r"window\.__NUXT__|id=\"__nuxt\"|id=\"__NUXT_DATA__\"", 95)],
314 "header": {"x-powered-by": [(r"(?i)nuxt", 95)]},
315 "implies": ["Vue.js"],
316 },
317 {
318 "name": "Angular",
319 "category": JS_FRAMEWORK,
320 "html": [(r"\bng-version=\"[\d.]+\"", 95), (r"<app-root[\s>]", 50), (r"\b_ngcontent-[a-z0-9-]+", 85)],
321 "script": [(r"/(?:main|polyfills|runtime)(?:-es\d+)?\.[0-9a-f]{16,}\.js", 25)],
322 },
323 {
324 "name": "Svelte",
325 "category": JS_FRAMEWORK,
326 "html": [(r"\bclass=\"[^\"]*\bsvelte-[a-z0-9]{5,}\b", 85), (r"__sveltekit_|data-sveltekit-", 95)],
327 "script": [(r"/_app/immutable/", 85)],
328 },
329 {
330 "name": "jQuery",
331 "category": JS_LIBRARY,
332 "script": [(r"jquery(?:[-.][\d.]+)?(?:\.slim)?(?:\.min)?\.js", 90), (r"code\.jquery\.com/", 95), (r"ajax\.googleapis\.com/ajax/libs/jquery/", 95)],
333 },
334 {
335 "name": "Gatsby",
336 "category": JS_FRAMEWORK,
337 "html": [(r"id=\"___gatsby\"", 95), (r"/page-data/app-data\.json", 80)],
338 "meta": {"generator": [(r"^Gatsby", 95)]},
339 "implies": ["React"],
340 },
341
342 {
343 "name": "Cloudflare",
344 "category": CDN,
345 "header": {"cf-ray": [(r".", 95)], "server": [(r"(?i)^cloudflare", 95)], "cf-cache-status": [(r".", 90)]},
346 "script": [(r"/cdn-cgi/(?:scripts|challenge-platform)/", 80), (r"cdnjs\.cloudflare\.com/", 20)],
347 "cookie": [(r"^(?:__cf_bm|__cflb|cf_clearance)$", 85)],
348 },
349 {
350 "name": "Vercel",
351 "category": HOSTING,
352 "header": {"x-vercel-id": [(r".", 95)], "x-vercel-cache": [(r".", 95)], "server": [(r"(?i)^vercel", 95)]},
353 },
354 {
355 "name": "Netlify",
356 "category": HOSTING,
357 "header": {"x-nf-request-id": [(r".", 95)], "server": [(r"(?i)^netlify", 95)]},
358 },
359 {
360 "name": "Amazon CloudFront",
361 "category": CDN,
362 "header": {"x-amz-cf-id": [(r".", 95)], "x-amz-cf-pop": [(r".", 95)], "via": [(r"(?i)cloudfront", 90)], "x-cache": [(r"(?i)cloudfront", 90)]},
363 },
364 {
365 "name": "Fastly",
366 "category": CDN,
367 "header": {"x-served-by": [(r"cache-[a-z]{3}\d+", 80)], "fastly-debug-digest": [(r".", 95)], "x-fastly-request-id": [(r".", 95)], "via": [(r"(?i)varnish", 30)]},
368 },
369 {
370 "name": "Akamai",
371 "category": CDN,
372 "header": {"x-akamai-transformed": [(r".", 95)], "akamai-grn": [(r".", 95)], "server": [(r"(?i)^AkamaiGHost|^AkamaiNetStorage", 95)]},
373 "cookie": [(r"^(?:ak_bmsc|bm_sv|_abck)$", 75)],
374 },
375
376 {
377 "name": "nginx",
378 "category": WEB_SERVER,
379 "header": {"server": [(r"(?i)^nginx", 95)]},
380 },
381 {
382 "name": "Apache HTTP Server",
383 "category": WEB_SERVER,
384 "header": {"server": [(r"(?i)^Apache(?!-Coyote)", 90)]},
385 },
386 {
387 "name": "LiteSpeed",
388 "category": WEB_SERVER,
389 "header": {"server": [(r"(?i)^LiteSpeed", 95)], "x-litespeed-cache": [(r".", 90)]},
390 },
391 {
392 "name": "Microsoft IIS",
393 "category": WEB_SERVER,
394 "header": {"server": [(r"(?i)^Microsoft-IIS", 95)], "x-powered-by": [(r"^ASP\.NET", 60)]},
395 },
396
397 {
398 "name": "Optimizely",
399 "category": AB_TESTING,
400 "script": [(r"cdn\.optimizely\.com/js/", 95)],
401 "html": [(r"window\.optimizely\s*=", 80)],
402 },
403 {
404 "name": "VWO",
405 "category": AB_TESTING,
406 "script": [(r"dev\.visualwebsiteoptimizer\.com/", 95)],
407 "html": [(r"_vwo_code|window\._vwo_", 90)],
408 "cookie": [(r"^_vwo_uuid", 80)],
409 },
410 {
411 "name": "Trustpilot",
412 "category": REVIEWS,
413 "script": [(r"widget\.trustpilot\.com/bootstrap/", 95)],
414 "html": [(r"\bclass=\"trustpilot-widget\"", 90)],
415 },
416 {
417 "name": "Yotpo",
418 "category": REVIEWS,
419 "script": [(r"(?:staticw2|cdn-widgetsrepository)\.yotpo\.com/", 95)],
420 "html": [(r"\byotpo-(?:main-widget|bottomline|reviews)\b|class=\"yotpo ", 85)],
421 },
422 {
423 "name": "Judge.me",
424 "category": REVIEWS,
425 "script": [(r"cdn\.judge\.me/|judgeme\.imgix\.net", 95)],
426 "html": [(r"\bjdgm-(?:widget|preview-badge|rev-widg)\b|jdgm\.SHOP_DOMAIN", 90)],
427 },
428
429 {
430 "name": "Google Fonts",
431 "category": FONTS,
432 "link": [(r"fonts\.googleapis\.com/css", 95), (r"fonts\.gstatic\.com", 60)],
433 "html": [(r"@import\s+url\(['\"]?https://fonts\.googleapis\.com/", 90)],
434 },
435 {
436 "name": "Adobe Fonts",
437 "category": FONTS,
438 "link": [(r"use\.typekit\.net/[a-z0-9]+\.css", 95)],
439 "script": [(r"use\.typekit\.net/[a-z0-9]+\.js", 95)],
440 "html": [(r"p\.typekit\.net|Typekit\.load", 80)],
441 },
442
443 {
444 "name": "Google Ads",
445 "category": ADVERTISING,
446 "script": [(r"googletagmanager\.com/gtag/js\?id=AW-", 95), (r"googleadservices\.com/pagead/conversion", 90)],
447 "html": [(r"gtag\(\s*['\"]config['\"]\s*,\s*['\"]AW-\d+", 95)],
448 },
449 {
450 "name": "Microsoft Clarity",
451 "category": ANALYTICS,
452 "script": [(r"clarity\.ms/tag/", 95)],
453 "html": [(r"www\.clarity\.ms/tag/", 90)],
454 },
455 {
456 "name": "Cookiebot",
457 "category": TAG_MANAGER,
458 "script": [(r"consent\.cookiebot\.com/", 95)],
459 },
460 {
461 "name": "OneTrust",
462 "category": TAG_MANAGER,
463 "script": [(r"cdn\.cookielaw\.org/|optanon\.blob\.core\.windows\.net", 95)],
464 "cookie": [(r"^OptanonConsent$", 85)],
465 },
466 {
467 "name": "Bootstrap",
468 "category": JS_LIBRARY,
469 "script": [(r"bootstrap(?:\.bundle)?(?:\.min)?\.js", 80)],
470 "link": [(r"bootstrap(?:\.min)?\.css", 80)],
471 },
472 {
473 "name": "Tailwind CSS",
474 "category": JS_LIBRARY,
475 "script": [(r"cdn\.tailwindcss\.com", 95)],
476 "html": [(r"--tw-(?:ring|shadow|translate)-", 75)],
477 },
478 {
479 "name": "PHP",
480 "category": WEB_SERVER,
481 "header": {"x-powered-by": [(r"(?i)^PHP/?", 90)]},
482 "cookie": [(r"^PHPSESSID$", 80)],
483 },
484 {
485 "name": "Express",
486 "category": WEB_SERVER,
487 "header": {"x-powered-by": [(r"(?i)^Express$", 90)]},
488 },
489]
490
491
492
493
494
495MX_PROVIDERS: list[tuple[str, str]] = [
496 (r"(?:^|\.)aspmx\d*\.l\.google\.com$|(?:^|\.)googlemail\.com$|(?:^|\.)smtp\.google\.com$|(?:^|\.)google\.com$", "Google Workspace"),
497 (r"\.mail\.protection\.outlook\.com$|\.outlook\.com$", "Microsoft 365"),
498 (r"(?:^|\.)zoho\.(?:com|eu|in|com\.au|jp|com\.cn)$|(?:^|\.)zohomail\.com$", "Zoho Mail"),
499 (r"(?:^|\.)protonmail\.ch$|(?:^|\.)proton\.me$", "Proton Mail"),
500 (r"(?:^|\.)messagingengine\.com$|(?:^|\.)fastmail\.com$", "Fastmail"),
501 (r"(?:^|\.)mimecast(?:-offshore)?\.com$|(?:^|\.)mimecast\.co\.za$", "Mimecast"),
502 (r"(?:^|\.)pphosted\.com$|(?:^|\.)ppe-hosted\.com$", "Proofpoint"),
503 (r"(?:^|\.)barracudanetworks\.com$", "Barracuda"),
504 (r"(?:^|\.)iphmx\.com$", "Cisco Secure Email"),
505 (r"(?:^|\.)mailgun\.org$", "Mailgun"),
506 (r"(?:^|\.)amazonaws\.com$|(?:^|\.)awsapps\.com$", "Amazon WorkMail / SES"),
507 (r"(?:^|\.)yandex\.(?:net|ru)$", "Yandex 360"),
508 (r"(?:^|\.)icloud\.com$|(?:^|\.)me\.com$", "iCloud Mail"),
509 (r"(?:^|\.)secureserver\.net$", "GoDaddy (Microsoft 365 / Workspace Email)"),
510 (r"(?:^|\.)ovh\.net$", "OVHcloud"),
511 (r"(?:^|\.)ionos\.(?:com|de|co\.uk)$|(?:^|\.)1and1\.com$", "IONOS"),
512 (r"(?:^|\.)hostinger\.com$", "Hostinger"),
513 (r"(?:^|\.)mx\.cloudflare\.net$", "Cloudflare Email Routing"),
514 (r"(?:^|\.)forwardemail\.net$", "Forward Email"),
515]
516
517
518SPF_SERVICES: list[tuple[str, str]] = [
519 (r"(?:^|\.)_spf\.google\.com$|(?:^|\.)googlemail\.com$", "Google Workspace"),
520 (r"(?:^|\.)spf\.protection\.outlook\.com$", "Microsoft 365"),
521 (r"(?:^|\.)sendgrid\.net$", "SendGrid"),
522 (r"(?:^|\.)mailgun\.org$", "Mailgun"),
523 (r"(?:^|\.)amazonses\.com$", "Amazon SES"),
524 (r"(?:^|\.)servers\.mcsv\.net$|(?:^|\.)mcsv\.net$", "Mailchimp"),
525 (r"(?:^|\.)mandrillapp\.com$", "Mailchimp Transactional (Mandrill)"),
526 (r"(?:^|\.)hubspotemail\.net$|(?:^|\.)hubspot\.com$", "HubSpot"),
527 (r"(?:^|\.)zoho\.(?:com|eu|in)$|(?:^|\.)zohomail\.com$", "Zoho"),
528 (r"(?:^|\.)spf\.protonmail\.ch$", "Proton Mail"),
529 (r"(?:^|\.)messagingengine\.com$", "Fastmail"),
530 (r"(?:^|\.)mimecast\.com$", "Mimecast"),
531 (r"(?:^|\.)pphosted\.com$", "Proofpoint"),
532 (r"(?:^|\.)salesforce\.com$|(?:^|\.)exacttarget\.com$", "Salesforce / Marketing Cloud"),
533 (r"(?:^|\.)mktomail\.com$", "Marketo"),
534 (r"(?:^|\.)zendesk\.com$", "Zendesk"),
535 (r"(?:^|\.)freshdesk\.com$", "Freshdesk"),
536 (r"(?:^|\.)helpscoutemail\.com$", "Help Scout"),
537 (r"(?:^|\.)intercom\.io$", "Intercom"),
538 (r"(?:^|\.)klaviyo\.com$", "Klaviyo"),
539 (r"(?:^|\.)shopify\.com$", "Shopify"),
540 (r"(?:^|\.)sparkpostmail\.com$", "SparkPost"),
541 (r"(?:^|\.)postmarkapp\.com$|(?:^|\.)mtasv\.net$", "Postmark"),
542 (r"(?:^|\.)sendinblue\.com$|(?:^|\.)brevo\.com$", "Brevo"),
543 (r"(?:^|\.)secureserver\.net$", "GoDaddy"),
544 (r"(?:^|\.)mailjet\.com$", "Mailjet"),
545 (r"(?:^|\.)atlassian\.net$", "Atlassian"),
546]
547
548
549TXT_VERIFICATIONS: list[tuple[str, str]] = [
550 (r"^google-site-verification=", "Google Search Console / Workspace"),
551 (r"^facebook-domain-verification=", "Meta Business"),
552 (r"^MS=ms\d+", "Microsoft 365"),
553 (r"^atlassian-domain-verification=", "Atlassian"),
554 (r"^apple-domain-verification=", "Apple"),
555 (r"^docusign=", "DocuSign"),
556 (r"^stripe-verification=", "Stripe"),
557 (r"^adobe-idp-site-verification=|^adobe-sign-verification=", "Adobe"),
558 (r"^hubspot-developer-verification=|^hubspot-domain-verification=", "HubSpot"),
559 (r"^zoom-domain-verification|^ZOOM_verify_", "Zoom"),
560 (r"^slack-domain-verification=", "Slack"),
561 (r"^dropbox-domain-verification=", "Dropbox"),
562 (r"^miro-verification=", "Miro"),
563 (r"^openai-domain-verification=", "OpenAI"),
564 (r"^zoho-verification=", "Zoho"),
565 (r"^yandex-verification:", "Yandex"),
566 (r"^globalsign-domain-verification=", "GlobalSign"),
567 (r"^shopify-verification-code=", "Shopify"),
568 (r"^klaviyo-site-verification=", "Klaviyo"),
569 (r"^notion-domain-verification=", "Notion"),
570 (r"^canva-site-verification=", "Canva"),
571 (r"^onetrust-domain-verification=", "OneTrust"),
572 (r"^mailru-verification:", "Mail.ru"),
573 (r"^cisco-ci-domain-verification=", "Cisco Webex"),
574 (r"^amazonses:", "Amazon SES"),
575 (r"^sendinblue-code:|^brevo-code:", "Brevo"),
576]