mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2026-01-31 07:43:09 +08:00
Merge pull request #6748 from projectdiscovery/dwisiswant0/fix/http/race-condition-regression
fix(http): race condition regression
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
@@ -62,6 +63,7 @@ var httpTestcases = []TestCaseInfo{
|
||||
{Path: "protocols/http/dsl-functions.yaml", TestCase: &httpDSLFunctions{}},
|
||||
{Path: "protocols/http/race-simple.yaml", TestCase: &httpRaceSimple{}},
|
||||
{Path: "protocols/http/race-multiple.yaml", TestCase: &httpRaceMultiple{}},
|
||||
{Path: "protocols/http/race-condition-with-delay.yaml", TestCase: &httpRaceWithDelay{}},
|
||||
{Path: "protocols/http/race-with-variables.yaml", TestCase: &httpRaceWithVariables{}},
|
||||
{Path: "protocols/http/stop-at-first-match.yaml", TestCase: &httpStopAtFirstMatch{}},
|
||||
{Path: "protocols/http/stop-at-first-match-with-extractors.yaml", TestCase: &httpStopAtFirstMatchWithExtractors{}},
|
||||
@@ -1156,6 +1158,51 @@ func (h *httpRaceMultiple) Execute(filePath string) error {
|
||||
return expectResultsCount(results, 5)
|
||||
}
|
||||
|
||||
type httpRaceWithDelay struct{}
|
||||
|
||||
// Execute executes a test case and returns an error if occurred
|
||||
func (h *httpRaceWithDelay) Execute(filePath string) error {
|
||||
var requestTimes []time.Time
|
||||
var mu sync.Mutex
|
||||
|
||||
router := httprouter.New()
|
||||
router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||
mu.Lock()
|
||||
requestTimes = append(requestTimes, time.Now())
|
||||
mu.Unlock()
|
||||
time.Sleep(2 * time.Second)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
})
|
||||
ts := httptest.NewServer(router)
|
||||
defer ts.Close()
|
||||
|
||||
results, err := testutils.RunNucleiTemplateAndGetResults(filePath, ts.URL, debug)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := expectResultsCount(results, 3); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if len(requestTimes) != 3 {
|
||||
return fmt.Errorf("expected 3 requests, got %d", len(requestTimes))
|
||||
}
|
||||
|
||||
// Check concurrency of first two requests (should be very close)
|
||||
if diff := requestTimes[1].Sub(requestTimes[0]); diff > 500*time.Millisecond {
|
||||
return fmt.Errorf("expected first 2 requests to be concurrent, diff: %v", diff)
|
||||
}
|
||||
|
||||
// Check delay of third request (should be after ~2s)
|
||||
if diff := requestTimes[2].Sub(requestTimes[0]); diff < 1500*time.Millisecond {
|
||||
return fmt.Errorf("expected 3rd request to be delayed, diff: %v", diff)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type httpRaceWithVariables struct{}
|
||||
|
||||
// Execute tests that variables and constants are properly resolved in race mode.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
id: race-condition-with-delay
|
||||
|
||||
info:
|
||||
name: Race Condition Testing with Delay
|
||||
author: pdteam
|
||||
severity: info
|
||||
description: |
|
||||
Test race condition handling with induced server delay.
|
||||
tags: test
|
||||
|
||||
http:
|
||||
- raw:
|
||||
- |
|
||||
GET / HTTP/1.1
|
||||
Host: {{Hostname}}
|
||||
- |
|
||||
GET / HTTP/1.1
|
||||
Host: {{Hostname}}
|
||||
- |
|
||||
GET / HTTP/1.1
|
||||
Host: {{Hostname}}
|
||||
|
||||
threads: 2
|
||||
race: true
|
||||
matchers:
|
||||
- type: status
|
||||
status:
|
||||
- 200
|
||||
@@ -501,7 +501,7 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, dynamicVa
|
||||
}
|
||||
|
||||
// verify if parallel elaboration was requested
|
||||
if request.Threads > 0 && len(request.Payloads) > 0 {
|
||||
if request.Threads > 0 && (len(request.Payloads) > 0 || request.Race) {
|
||||
return request.executeParallelHTTP(input, dynamicValues, callback)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user