Skip to content

Commit

Permalink
feat: make discoverable scans running in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
emmanuelgautier committed Dec 19, 2024
1 parent 7d548a8 commit c6d1839
Showing 1 changed file with 40 additions and 16 deletions.
56 changes: 40 additions & 16 deletions scan/discover/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,50 @@ func ExtractBaseURL(inputURL *url.URL) *url.URL {

func ScanURLs(scanUrls []string, op *operation.Operation, securityScheme *auth.SecurityScheme, r *report.ScanReport, vulnReport *report.IssueReport) (*report.ScanReport, error) {
securitySchemes := []*auth.SecurityScheme{securityScheme}

base := ExtractBaseURL(&op.URL)
for _, path := range scanUrls {
newOperation, err := operation.NewOperation(http.MethodGet, base.ResolveReference(&url.URL{Path: path}).String(), nil, op.Client)
newOperation.SetSecuritySchemes(securitySchemes)
if err != nil {
return r, err
}
chunkSize := 20
results := make(chan *scan.IssueScanAttempt, len(scanUrls))
errors := make(chan error, len(scanUrls))

attempt, err := scan.ScanURL(newOperation, securityScheme)
if err != nil {
return r, err
for i := 0; i < len(scanUrls); i += chunkSize {
end := i + chunkSize
if end > len(scanUrls) {
end = len(scanUrls)
}
chunk := scanUrls[i:end]

go func(chunk []string) {
for _, path := range chunk {
newOperation, err := operation.NewOperation(http.MethodGet, base.ResolveReference(&url.URL{Path: path}).String(), nil, op.Client)
newOperation.SetSecuritySchemes(securitySchemes)
if err != nil {
errors <- err
return
}

r.AddScanAttempt(attempt)
if attempt.Response.GetStatusCode() == http.StatusOK { // TODO: check if the response contains the expected content
r.WithData(DiscoverData{
URL: attempt.Request.GetURL(),
}).AddIssueReport(vulnReport.Fail()).End()
return r, nil
attempt, err := scan.ScanURL(newOperation, securityScheme)
if err != nil {
errors <- err
return
}

results <- attempt
}
}(chunk)
}

for i := 0; i < len(scanUrls); i++ {
select {
case attempt := <-results:
r.AddScanAttempt(attempt)
if attempt.Response.GetStatusCode() == http.StatusOK { // TODO: check if the response contains the expected content
r.WithData(DiscoverData{
URL: attempt.Request.GetURL(),
}).AddIssueReport(vulnReport.Fail()).End()
return r, nil
}
case err := <-errors:
return r, err
}
}

Expand Down

0 comments on commit c6d1839

Please sign in to comment.