From 8358b8d7d80cf3f31e86c93bccead3a8f09cb3b4 Mon Sep 17 00:00:00 2001 From: Tarun Koyalwar Date: Mon, 8 Apr 2024 18:08:40 +0530 Subject: [PATCH 1/2] explicitly handle edgecase #4993 instead of hot fix --- pkg/protocols/http/http.go | 41 +++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/pkg/protocols/http/http.go b/pkg/protocols/http/http.go index 261d3b5656..08fcfb33c0 100644 --- a/pkg/protocols/http/http.go +++ b/pkg/protocols/http/http.go @@ -9,6 +9,7 @@ import ( json "github.com/json-iterator/go" "github.com/pkg/errors" + "github.com/projectdiscovery/gologger" "github.com/projectdiscovery/nuclei/v3/pkg/fuzz" "github.com/projectdiscovery/nuclei/v3/pkg/operators" "github.com/projectdiscovery/nuclei/v3/pkg/operators/matchers" @@ -20,7 +21,6 @@ import ( httputil "github.com/projectdiscovery/nuclei/v3/pkg/protocols/utils/http" "github.com/projectdiscovery/rawhttp" "github.com/projectdiscovery/retryablehttp-go" - "github.com/projectdiscovery/utils/env" fileutil "github.com/projectdiscovery/utils/file" ) @@ -436,14 +436,31 @@ func (request *Request) Compile(options *protocols.ExecutorOptions) error { } } if len(request.Payloads) > 0 { - // specifically for http requests high concurrency and and threads will lead to memory exausthion, hence reduce the maximum parallelism - if protocolstate.IsLowOnMemory() { - request.Threads = protocolstate.GuardThreadsOrDefault(request.Threads) + // due to limitation of https://github.com/projectdiscovery/nuclei/issues/5015 + // use of dynamic extractor is not allowed with payloads and will be executed via normal engine + // without parallelism by forcing threads value to 0 + + // this limitation will be removed once we have a better way to handle dynamic extractors with payloads + hasMultiReqests := false + if len(request.Raw)+len(request.Path) > 1 { + hasMultiReqests = true } - // if we have payloads, adjust threads if none specified - // We only do this in case we have more payload requests than the - // specified concurrency threshold. - if request.generator.NewIterator().Total() > PayloadAutoConcurrencyThreshold { + // look for dynamic extractor ( internal: true with named extractor) + hasNamedExtractor := false + for _, extractor := range request.Extractors { + if extractor.Internal && extractor.Name != "" { + hasNamedExtractor = true + break + } + } + if hasNamedExtractor && hasMultiReqests { + gologger.Warning().Label(options.TemplateID).Msgf("Setting thread count to 0 because dynamic extractors are not supported with payloads yet") + request.Threads = 0 + } else { + // specifically for http requests high concurrency and and threads will lead to memory exausthion, hence reduce the maximum parallelism + if protocolstate.IsLowOnMemory() { + request.Threads = protocolstate.GuardThreadsOrDefault(request.Threads) + } request.Threads = options.GetThreadsForNPayloadRequests(request.Requests(), request.Threads) } } @@ -472,11 +489,3 @@ func (request *Request) Requests() int { } return len(request.Path) } - -// PayloadAutoConcurrencyThreshold is the threshold for auto adjusting concurrency -// for payloads in a template. -var PayloadAutoConcurrencyThreshold int - -func init() { - PayloadAutoConcurrencyThreshold = env.GetEnvOrDefault[int]("NUCLEI_PAYLOAD_AUTO_CONCURRENCY_THRESHOLD", 100) -} From 417f5557b8409cd83828468238db47771b32a502 Mon Sep 17 00:00:00 2001 From: Tarun Koyalwar Date: Mon, 8 Apr 2024 18:50:07 +0530 Subject: [PATCH 2/2] fix typo --- pkg/protocols/http/http.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pkg/protocols/http/http.go b/pkg/protocols/http/http.go index 08fcfb33c0..b98fd917a5 100644 --- a/pkg/protocols/http/http.go +++ b/pkg/protocols/http/http.go @@ -436,24 +436,25 @@ func (request *Request) Compile(options *protocols.ExecutorOptions) error { } } if len(request.Payloads) > 0 { - // due to limitation of https://github.com/projectdiscovery/nuclei/issues/5015 - // use of dynamic extractor is not allowed with payloads and will be executed via normal engine - // without parallelism by forcing threads value to 0 + // Due to a known issue (https://github.com/projectdiscovery/nuclei/issues/5015), + // dynamic extractors cannot be used with payloads. To address this, + // execution is handled by the standard engine without concurrency, + // achieved by setting the thread count to 0. // this limitation will be removed once we have a better way to handle dynamic extractors with payloads - hasMultiReqests := false + hasMultipleRequests := false if len(request.Raw)+len(request.Path) > 1 { - hasMultiReqests = true + hasMultipleRequests = true } // look for dynamic extractor ( internal: true with named extractor) - hasNamedExtractor := false + hasNamedInternalExtractor := false for _, extractor := range request.Extractors { if extractor.Internal && extractor.Name != "" { - hasNamedExtractor = true + hasNamedInternalExtractor = true break } } - if hasNamedExtractor && hasMultiReqests { + if hasNamedInternalExtractor && hasMultipleRequests { gologger.Warning().Label(options.TemplateID).Msgf("Setting thread count to 0 because dynamic extractors are not supported with payloads yet") request.Threads = 0 } else {