diff --git a/bgptools/privacy_test.go b/bgptools/privacy_test.go index de9f214..10d24f3 100644 --- a/bgptools/privacy_test.go +++ b/bgptools/privacy_test.go @@ -54,13 +54,13 @@ func TestStructuredReportErrorsDoNotExposeRemoteURLs(t *testing.T) { if err != nil { t.Fatal(err) } - for _, forbidden := range []string{"token=", "key=", "secret", "userinfo@"} { + for _, forbidden := range []string{"private.example", "token=", "key=", "secret", "userinfo@", `"geofeed_urls"`, `"port43"`, `"server"`, `"url"`} { if strings.Contains(string(encoded), forbidden) { t.Fatalf("structured report leaked %q: %s", forbidden, encoded) } } - if report.RDAP == nil || len(report.RDAP.GeofeedURLs) != 1 || report.RDAP.GeofeedURLs[0] != "https://private.example/geofeed" || report.Geofeeds[0].URL != "https://private.example/geofeed" { - t.Fatalf("geofeed URL was not sanitized consistently: %+v", report) + if report.RDAP == nil || len(report.RDAP.GeofeedURLs) != 1 || report.Geofeeds[0].Status != ReportError { + t.Fatalf("internal geofeed processing was not preserved: %+v", report) } } @@ -95,3 +95,38 @@ func TestRemoteFetchErrorsDoNotExposeSourceURL(t *testing.T) { }) } } + +func TestStructuredReportOmitsServiceLocationsButKeepsProbeEvidence(t *testing.T) { + report := IPBGPReport{ + Status: ReportPartial, + RDAP: &RDAPRecord{ + Port43: "whois.private.example:43", + GeofeedURLs: []string{"https://private.example/rdap-geofeed.csv"}, + }, + WHOIS: &WHOISRecord{ + Server: "whois.private.example:43", + Status: ReportAvailable, + GeofeedURLs: []string{"https://private.example/whois-geofeed.csv"}, + }, + Geofeeds: []GeofeedResult{{ + URL: "https://private.example/geofeed.csv", + Status: ReportAvailable, + HTTPStatus: http.StatusOK, + Bytes: 128, + }}, + } + encoded, err := json.Marshal(report) + if err != nil { + t.Fatal(err) + } + for _, forbidden := range []string{"private.example", "whois.private", `"geofeed_urls"`, `"port43"`, `"server"`, `"url"`} { + if strings.Contains(string(encoded), forbidden) { + t.Fatalf("structured report leaked %q: %s", forbidden, encoded) + } + } + for _, expected := range []string{`"status":"available"`, `"http_status":200`, `"bytes":128`} { + if !strings.Contains(string(encoded), expected) { + t.Fatalf("structured report lost probe evidence %q: %s", expected, encoded) + } + } +} diff --git a/bgptools/rdap.go b/bgptools/rdap.go index d25f71d..80374d5 100644 --- a/bgptools/rdap.go +++ b/bgptools/rdap.go @@ -36,9 +36,9 @@ type RDAPRecord struct { Prefixes []string `json:"prefixes,omitempty"` RegistrationDate *time.Time `json:"registration_date,omitempty"` LastChangedDate *time.Time `json:"last_changed_date,omitempty"` - GeofeedURLs []string `json:"geofeed_urls,omitempty"` + GeofeedURLs []string `json:"-"` Entities []RDAPEntity `json:"entities,omitempty"` - Port43 string `json:"port43,omitempty"` + Port43 string `json:"-"` Status []string `json:"status,omitempty"` Source string `json:"source"` } diff --git a/bgptools/report.go b/bgptools/report.go index e7fe437..9436605 100644 --- a/bgptools/report.go +++ b/bgptools/report.go @@ -46,10 +46,10 @@ type RIRInfo struct { Status ReportStatus `json:"status"` } -// GeofeedResult contains an RDAP/WHOIS geofeed URL and, when requested, the -// bounded fetch result. The payload itself is not retained in the report. +// GeofeedResult contains the bounded fetch result. URL remains internal so +// reports expose the probe outcome without disclosing the service location. type GeofeedResult struct { - URL string `json:"url"` + URL string `json:"-"` Status ReportStatus `json:"status"` HTTPStatus int `json:"http_status,omitempty"` Bytes int64 `json:"bytes,omitempty"` @@ -59,11 +59,11 @@ type GeofeedResult struct { // WHOISRecord is the small, structured subset used when RDAP is unavailable // or missing required fields. Raw port-43 text is never returned. type WHOISRecord struct { - Server string `json:"server"` + Server string `json:"-"` Status ReportStatus `json:"status"` Prefixes []string `json:"prefixes,omitempty"` RegistrationDate *time.Time `json:"registration_date,omitempty"` - GeofeedURLs []string `json:"geofeed_urls,omitempty"` + GeofeedURLs []string `json:"-"` RIR RIRInfo `json:"rir"` } diff --git a/model/model.go b/model/model.go index 133ba6c..5c41d76 100644 --- a/model/model.go +++ b/model/model.go @@ -2,7 +2,7 @@ package model import "time" -const BackTraceVersion = "v0.0.18" +const BackTraceVersion = "v0.0.19" var EnableLoger = false