mirror of
https://github.com/Horizontal42/netsleuth.git
synced 2026-11-10 21:32:04 +03:00
ip_geo: never let cf-trace's own ip leak into a target lookup
cf-trace has no way to describe an arbitrary target — it always echoes the ip of whoever is making the http request. gather_identity included it in the merge candidates unconditionally, so 'netcheck --target 8.8.8.8' spliced this machine's own connecting ip onto 8.8.8.8's asn/city/org fields from the other providers, producing a report that named an ip that was neither the target nor honestly labeled as the local egress. exclude cf-trace from the merge whenever an explicit target ip was requested; it's still fetched and returned separately for the connection section's own colo/warp fields.
This commit is contained in:
parent
5e4aa8b101
commit
5da12ae629
2 changed files with 40 additions and 1 deletions
|
|
@ -247,7 +247,10 @@ async def gather_identity(
|
||||||
flags = provider_flags(payloads["ip-api"]) if isinstance(payloads["ip-api"], dict) else {}
|
flags = provider_flags(payloads["ip-api"]) if isinstance(payloads["ip-api"], dict) else {}
|
||||||
|
|
||||||
candidates: list[tuple[str, IpGeo]] = []
|
candidates: list[tuple[str, IpGeo]] = []
|
||||||
if cf:
|
if cf and not ip:
|
||||||
|
# cf-trace can only ever describe the machine making the request, never an
|
||||||
|
# arbitrary target — folding it in during a target lookup would splice this
|
||||||
|
# host's own IP onto the target's asn/geo fields from the other providers.
|
||||||
candidates.append(("cf-trace", IpGeo(ip=cf.ip, country_code=cf.loc, sources={})))
|
candidates.append(("cf-trace", IpGeo(ip=cf.ip, country_code=cf.loc, sources={})))
|
||||||
for name, normalizer in (
|
for name, normalizer in (
|
||||||
("ip-api", normalize_ip_api),
|
("ip-api", normalize_ip_api),
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import httpx
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from netcheck.config import Providers
|
||||||
from netcheck.ip_geo import (
|
from netcheck.ip_geo import (
|
||||||
classify_ip_type,
|
classify_ip_type,
|
||||||
|
gather_identity,
|
||||||
normalize_freeipapi,
|
normalize_freeipapi,
|
||||||
normalize_ip_api,
|
normalize_ip_api,
|
||||||
normalize_ipinfo,
|
normalize_ipinfo,
|
||||||
|
|
@ -195,3 +198,36 @@ def test_dual_stack_agreement_produces_no_note():
|
||||||
def test_dual_stack_comparison_needs_both_sides():
|
def test_dual_stack_comparison_needs_both_sides():
|
||||||
assert dual_stack_mismatch(IpGeo(asn="AS64500"), None) is None
|
assert dual_stack_mismatch(IpGeo(asn="AS64500"), None) is None
|
||||||
assert dual_stack_mismatch(None, IpGeo(asn="AS64500")) is None
|
assert dual_stack_mismatch(None, IpGeo(asn="AS64500")) is None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_gather_identity_for_a_target_never_reports_this_hosts_own_ip(httpx_mock):
|
||||||
|
httpx_mock.add_response(
|
||||||
|
url="https://www.cloudflare.com/cdn-cgi/trace",
|
||||||
|
text="ip=203.0.113.9\nloc=NL\nwarp=off\ngateway=off\nrbi=off\n",
|
||||||
|
)
|
||||||
|
httpx_mock.add_response(
|
||||||
|
url="http://ip-api.com/json/8.8.8.8",
|
||||||
|
json={
|
||||||
|
"status": "success",
|
||||||
|
"query": "8.8.8.8",
|
||||||
|
"as": "AS15169 GOOGLE",
|
||||||
|
"org": "Google LLC",
|
||||||
|
"country": "United States",
|
||||||
|
"countryCode": "US",
|
||||||
|
"city": "Ashburn",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
httpx_mock.add_response(url="https://freeipapi.com/api/json/8.8.8.8", json={})
|
||||||
|
httpx_mock.add_response(url="https://ipinfo.io/8.8.8.8json", json={})
|
||||||
|
httpx_mock.add_response(url="https://ipwho.is/8.8.8.8", json={"success": False})
|
||||||
|
httpx_mock.add_response(
|
||||||
|
url="https://stat.ripe.net/data/network-info/data.json?resource=8.8.8.8",
|
||||||
|
json={"status": "ok", "data": {"asns": ["15169"]}},
|
||||||
|
)
|
||||||
|
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
merged, cf, _flags, _raw = await gather_identity(client, Providers(), ip="8.8.8.8")
|
||||||
|
|
||||||
|
assert merged.ip == "8.8.8.8"
|
||||||
|
assert merged.asn == "AS15169"
|
||||||
|
assert cf is not None and cf.ip == "203.0.113.9"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue