"""Expected provider domains (cloud, CDN, OS, PKI). Used to lower severity, never to hide an observation. Extend with the ANALYZER_BENIGN_DOMAINS environment variable (comma-separated suffixes). """ from __future__ import annotations import os from typing import Optional BENIGN_SUFFIXES: set[str] = { # Apple "apple.com", "aaplimg.com", "icloud.com", "apple-dns.net", "cdn-apple.com", "mzstatic.com", "itunes-apple.com", "apple.map.fastly.net", "push.apple.com", "ls-apple.com.akadns.net", "edge.apple", "apple-cloudkit.com", # Akamai "akadns.net", "akamai.net", "akamaiedge.net", "akamai.com", "akamaized.net", "akamaihd.net", # AWS "amazonaws.com", "cloudfront.net", "awsstatic.com", "aws.dev", "amazon.com", # Google / Firebase "googleapis.com", "google.com", "gstatic.com", "ggpht.com", "youtube.com", "crashlytics.com", "firebaseio.com", "firebase.com", "app-measurement.com", "googleusercontent.com", "google-analytics.com", "doubleclick.net", "1e100.net", "googlevideo.com", "gvt1.com", "gvt2.com", # Apple analytics endpoint used by many apps "app-analytics-services.com", # CDNs "fastly.net", "fbcdn.net", "cloudflare.com", "cloudflare.net", "cloudflare-dns.com", "edgekey.net", "edgesuite.net", "llnwd.net", "cdn77.org", "azureedge.net", "aliyuncs.com", "alicdn.com", # Microsoft "microsoft.com", "windows.net", "azure.com", "windowsupdate.com", "office.com", "msftncsi.com", "live.com", "msftconnecttest.com", "office365.com", # PKI / time "digicert.com", "sectigo.com", "letsencrypt.org", "globalsign.com", "godaddy.com", "ntp.org", "pool.ntp.org", "time.apple.com", "time.google.com", "time.windows.com", # Reverse-DNS / special-use "in-addr.arpa", "ip6.arpa", "resolver.arpa", "arpa", "local", "home.arpa", } def _load_extra() -> set[str]: raw = os.environ.get("ANALYZER_BENIGN_DOMAINS", "") return {s.strip().lower().lstrip(".") for s in raw.split(",") if s.strip()} _EXTRA = _load_extra() def is_benign(name: Optional[str]) -> bool: """Whether a host name belongs to an expected provider.""" if not name: return False n = str(name).rstrip(".").lower() return any(n == s or n.endswith("." + s) for s in BENIGN_SUFFIXES | _EXTRA) def benign_name_for_ip(ctx, ip: Optional[str]) -> Optional[str]: """Return a benign provider name that resolved to the address, if any.""" for name in sorted(ctx.names_for_ip(ip)): if is_benign(name): return name return None