mirror of
https://github.com/oneclickvirt/backtrace.git
synced 2026-07-23 11:20:13 +08:00
98 lines
3.1 KiB
Go
98 lines
3.1 KiB
Go
package bgptools
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
type privacyRoundTripper func(*http.Request) (*http.Response, error)
|
|
|
|
func (fn privacyRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
|
|
return fn(request)
|
|
}
|
|
|
|
func TestStructuredReportErrorsDoNotExposeRemoteURLs(t *testing.T) {
|
|
var rdap *httptest.Server
|
|
rdap = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
_, _ = fmt.Fprintf(w, `{"handle":"TEST","links":[{"rel":"geofeed","href":"https://private.example/geofeed?token=secret"}]}`)
|
|
}))
|
|
defer rdap.Close()
|
|
failing := &http.Client{Transport: privacyRoundTripper(func(request *http.Request) (*http.Response, error) {
|
|
return nil, errors.New("dial " + request.URL.String())
|
|
})}
|
|
report, err := QueryIPBGPReport(context.Background(), "192.0.2.1", IPBGPReportConfig{
|
|
RDAPClient: rdap.Client(),
|
|
RDAPBaseURL: rdap.URL,
|
|
FetchGeofeed: true,
|
|
GeofeedClient: failing,
|
|
ResolveASN: func(context.Context, string) (string, error) {
|
|
return "", errors.New("resolver https://private.example/asn?key=secret")
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, source := range report.Sources {
|
|
for _, field := range []string{source.Source, source.Error} {
|
|
for _, forbidden := range []string{"private.example", "token=", "key=", "secret"} {
|
|
if strings.Contains(field, forbidden) {
|
|
t.Fatalf("structured source leaked %q: %+v", forbidden, source)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if len(report.Geofeeds) != 1 || report.Geofeeds[0].Error != "request_failed" {
|
|
t.Fatalf("geofeed error was not stabilized: %+v", report.Geofeeds)
|
|
}
|
|
encoded, err := json.Marshal(report)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, forbidden := range []string{"token=", "key=", "secret", "userinfo@"} {
|
|
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)
|
|
}
|
|
}
|
|
|
|
func TestRemoteFetchErrorsDoNotExposeSourceURL(t *testing.T) {
|
|
client := &http.Client{Transport: privacyRoundTripper(func(request *http.Request) (*http.Response, error) {
|
|
return nil, errors.New("dial " + request.URL.String())
|
|
})}
|
|
tests := []struct {
|
|
name string
|
|
run func() error
|
|
}{
|
|
{name: "ASN metadata", run: func() error {
|
|
_, err := fetchASNMetadata(context.Background(), client, "https://private.example/asn?token=secret")
|
|
return err
|
|
}},
|
|
{name: "RDAP", run: func() error {
|
|
_, err := QueryRDAP(context.Background(), "192.0.2.1", client, "https://private.example/rdap?token=secret")
|
|
return err
|
|
}},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
err := test.run()
|
|
if err == nil {
|
|
t.Fatal("expected request failure")
|
|
}
|
|
for _, forbidden := range []string{"private.example", "token=", "secret"} {
|
|
if strings.Contains(err.Error(), forbidden) {
|
|
t.Fatalf("error leaked %q: %v", forbidden, err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|