From ae80ddae618095b272459636ae896ed2cda93e0a Mon Sep 17 00:00:00 2001 From: Douglas Danger Manley Date: Wed, 13 Aug 2025 09:13:33 -0400 Subject: [PATCH] Prevent a netlas nil pointer dereference This uses two _different_ variables for the two _different_ HTTP requests, since two `defer` functions referenced the same `resp` variable. This setup could cause a nil pointer dereference in the following scenario: 1. The first request succeeds (a `defer` on `resp` is added). 2. The second request fails (which sets `resp` to nil, and then the first `defer` attempts to reference `resp.Body`). This change prevents that by not reusing the same variable for the second request. --- pkg/subscraping/sources/netlas/netlas.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/subscraping/sources/netlas/netlas.go b/pkg/subscraping/sources/netlas/netlas.go index c29bc2c8b..cd9f612e6 100644 --- a/pkg/subscraping/sources/netlas/netlas.go +++ b/pkg/subscraping/sources/netlas/netlas.go @@ -63,7 +63,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se // Pick an API key randomApiKey := subscraping.PickRandom(s.apiKeys, s.Name()) - resp, err := session.HTTPRequest(ctx, http.MethodGet, countUrl, "", map[string]string{ + resp1, err := session.HTTPRequest(ctx, http.MethodGet, countUrl, "", map[string]string{ "accept": "application/json", "X-API-Key": randomApiKey, }, nil, subscraping.BasicAuth{}) @@ -72,19 +72,19 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err} s.errors++ return - } else if resp.StatusCode != 200 { - results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("request rate limited with status code %d", resp.StatusCode)} + } else if resp1.StatusCode != 200 { + results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("request rate limited with status code %d", resp1.StatusCode)} s.errors++ return } defer func() { - if err := resp.Body.Close(); err != nil { + if err := resp1.Body.Close(); err != nil { results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err} s.errors++ } }() - body, err := io.ReadAll(resp.Body) + body, err := io.ReadAll(resp1.Body) if err != nil { results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("error reading ressponse body")} s.errors++ @@ -120,7 +120,7 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se // Pick an API key randomApiKey = subscraping.PickRandom(s.apiKeys, s.Name()) - resp, err = session.HTTPRequest(ctx, http.MethodPost, apiUrl, "", map[string]string{ + resp2, err := session.HTTPRequest(ctx, http.MethodPost, apiUrl, "", map[string]string{ "accept": "application/json", "X-API-Key": randomApiKey, "Content-Type": "application/json"}, strings.NewReader(string(jsonRequestBody)), subscraping.BasicAuth{}) @@ -130,20 +130,20 @@ func (s *Source) Run(ctx context.Context, domain string, session *subscraping.Se return } defer func() { - if err := resp.Body.Close(); err != nil { + if err := resp2.Body.Close(); err != nil { results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err} s.errors++ } }() - body, err = io.ReadAll(resp.Body) + body, err = io.ReadAll(resp2.Body) if err != nil { results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("error reading ressponse body")} s.errors++ return } - if resp.StatusCode == 429 { - results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("request rate limited with status code %d", resp.StatusCode)} + if resp2.StatusCode == 429 { + results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("request rate limited with status code %d", resp2.StatusCode)} s.errors++ return }