Kaistone Radar uses IP-based detection to flag visitors from infrastructure networks as
“Infrastructure Bot,” targeting the CGNAT address range defined by RFC 6598
(100.64.0.0/10). However, confirmed Anthropic infrastructure IPs observed in the
hit log fall outside this range, causing them to be classified as “Unknown / Human”
despite clearly being automated infrastructure traffic.
The isCGNAT() function in beacon.mjs checks whether an IPv4 address
falls within 100.64.0.0 - 100.127.255.255 (the 100.64.0.0/10 block).
This is the range reserved by RFC 6598 for Carrier-Grade NAT. The assumption is that hits from
this range on a public-facing site indicate infrastructure or internal network traffic rather
than end-user browsers.
The current detection logic:
function isCGNAT(ip) {
if (!ip || ip.includes(':')) return false;
const parts = ip.split('.').map(Number);
if (parts.length !== 4) return false;
// 100.64.0.0/10 = 100.64.0.0 - 100.127.255.255
return parts[0] === 100 && parts[1] >= 64 && parts[1] <= 127;
}
The hit log contains multiple visits from HeadlessChrome/131 on Linux with IPs in the
100.x.x.x range but below the 100.64.0.0 threshold:
| IP Address | User-Agent | Detected As | In CGNAT Range? |
|---|---|---|---|
100.48.90.91 |
HeadlessChrome/131.0.6778.0 | Headless Chrome | No (below 100.64) |
100.55.86.86 |
HeadlessChrome/131.0.6778.0 | Headless Chrome | No (below 100.64) |
These IPs share the same HeadlessChrome/131 user-agent and Linux platform as other hits from
IPs within the 100.64.0.0/10 range, strongly suggesting they originate from the
same Anthropic infrastructure. The 100.0.0.0/8 block is not assigned to any
regional internet registry for public allocation — addresses in 100.0.0.0 - 100.63.255.255
are either IANA-reserved or used internally by large organizations.
Any hit from an IP in the 100.x.x.x range on a public-facing website is almost
certainly infrastructure traffic, not an end user. By only checking the RFC 6598 subset, the
detector misses a portion of automated infrastructure visits. These misclassified hits inflate
the “Unknown / Human” count and reduce the accuracy of the bot identification
breakdown on the dashboard.
Since the user-agent detection still catches these as “Headless Chrome,” the impact is limited to the IP-based classification layer. However, if a future bot uses a standard browser user-agent from one of these IPs, it would be entirely invisible to both detection mechanisms.
Widen the isCGNAT() check to cover 100.0.0.0 - 100.127.255.255
(i.e., first octet equals 100 and second octet is less than 128). This captures both the
RFC 6598 range and the adjacent addresses observed in Anthropic infrastructure traffic:
function isCGNAT(ip) {
if (!ip || ip.includes(':')) return false;
const parts = ip.split('.').map(Number);
if (parts.length !== 4) return false;
// 100.0.0.0 - 100.127.255.255
return parts[0] === 100 && parts[1] < 128;
}
An alternative is to rename the function to isInfrastructureIP() and maintain
a list of known infrastructure ranges (CGNAT, AWS internal, etc.) rather than relying on a
single CIDR block.
Beacon source: netlify/functions/beacon.mjs
RFC 6598: IANA-Reserved IPv4 Prefix for Shared Address Space
Dashboard: /dashboard/
Findings index: /findings/