package sources import ( "context" "net/http" "net/http/httptest" "testing" "time" "github.com/salvacybersec/keyhunter/pkg/providers" "github.com/salvacybersec/keyhunter/pkg/recon" ) func sandboxesTestRegistry() *providers.Registry { return providers.NewRegistryFromProviders([]providers.Provider{ {Name: "openai", Keywords: []string{"sk-proj-"}}, }) } // sandboxesTestServer serves: // - /codepen-search : HTML with pen anchors // - /jsfiddle-search : JSON with results // - /fail-search : 500 to exercise per-platform failure tolerance func sandboxesTestServer(t *testing.T) *httptest.Server { t.Helper() mux := http.NewServeMux() mux.HandleFunc("/codepen-search", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html") _, _ = w.Write([]byte(`
one two skip `)) }) mux.HandleFunc("/jsfiddle-search", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`{"results":[ {"url":"https://jsfiddle.net/u/abcd1234/"}, {"url":"https://jsfiddle.net/u/wxyz5678/"} ]}`)) }) mux.HandleFunc("/fail-search", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte("boom")) }) return httptest.NewServer(mux) } func newSandboxesTestSource(srvURL string, plats []subPlatform) *SandboxesSource { return &SandboxesSource{ Platforms: plats, Registry: sandboxesTestRegistry(), Limiters: recon.NewLimiterRegistry(), Client: NewClient(), BaseURL: srvURL, } } func TestSandboxes_Sweep_HTMLAndJSON(t *testing.T) { srv := sandboxesTestServer(t) defer srv.Close() plats := []subPlatform{ {Name: "codepen", SearchPath: "/codepen-search?q=%s", ResultLinkRegex: `^/[^/]+/pen/[a-zA-Z0-9]+$`, IsJSON: false}, {Name: "jsfiddle", SearchPath: "/jsfiddle-search?q=%s", IsJSON: true, JSONItemsKey: "results", JSONURLKey: "url"}, } src := newSandboxesTestSource(srv.URL, plats) out := make(chan recon.Finding, 32) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := src.Sweep(ctx, "", out); err != nil { t.Fatalf("Sweep err: %v", err) } close(out) var findings []recon.Finding for f := range out { findings = append(findings, f) } // codepen: 2 hits, jsfiddle: 2 hits if len(findings) != 4 { t.Fatalf("expected 4 findings, got %d: %+v", len(findings), findings) } platforms := map[string]int{} for _, f := range findings { if f.SourceType != "recon:sandboxes" { t.Errorf("unexpected SourceType: %s", f.SourceType) } // sub-platform identifier is encoded into KeyMasked as "platform=