Skip to content

Commit f159e8f

Browse files
fix dynamic extractor + payloads edgecase by sending req sequentially (#5016)
* explicitly handle edgecase #4993 instead of hot fix * fix typo
1 parent a844e6f commit f159e8f

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

pkg/protocols/http/http.go

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
json "github.com/json-iterator/go"
1010
"github.com/pkg/errors"
1111

12+
"github.com/projectdiscovery/gologger"
1213
"github.com/projectdiscovery/nuclei/v3/pkg/fuzz"
1314
"github.com/projectdiscovery/nuclei/v3/pkg/operators"
1415
"github.com/projectdiscovery/nuclei/v3/pkg/operators/matchers"
@@ -20,7 +21,6 @@ import (
2021
httputil "github.com/projectdiscovery/nuclei/v3/pkg/protocols/utils/http"
2122
"github.com/projectdiscovery/rawhttp"
2223
"github.com/projectdiscovery/retryablehttp-go"
23-
"github.com/projectdiscovery/utils/env"
2424
fileutil "github.com/projectdiscovery/utils/file"
2525
)
2626

@@ -436,14 +436,32 @@ func (request *Request) Compile(options *protocols.ExecutorOptions) error {
436436
}
437437
}
438438
if len(request.Payloads) > 0 {
439-
// specifically for http requests high concurrency and and threads will lead to memory exausthion, hence reduce the maximum parallelism
440-
if protocolstate.IsLowOnMemory() {
441-
request.Threads = protocolstate.GuardThreadsOrDefault(request.Threads)
439+
// Due to a known issue (https://github.com/projectdiscovery/nuclei/issues/5015),
440+
// dynamic extractors cannot be used with payloads. To address this,
441+
// execution is handled by the standard engine without concurrency,
442+
// achieved by setting the thread count to 0.
443+
444+
// this limitation will be removed once we have a better way to handle dynamic extractors with payloads
445+
hasMultipleRequests := false
446+
if len(request.Raw)+len(request.Path) > 1 {
447+
hasMultipleRequests = true
442448
}
443-
// if we have payloads, adjust threads if none specified
444-
// We only do this in case we have more payload requests than the
445-
// specified concurrency threshold.
446-
if request.generator.NewIterator().Total() > PayloadAutoConcurrencyThreshold {
449+
// look for dynamic extractor ( internal: true with named extractor)
450+
hasNamedInternalExtractor := false
451+
for _, extractor := range request.Extractors {
452+
if extractor.Internal && extractor.Name != "" {
453+
hasNamedInternalExtractor = true
454+
break
455+
}
456+
}
457+
if hasNamedInternalExtractor && hasMultipleRequests {
458+
gologger.Warning().Label(options.TemplateID).Msgf("Setting thread count to 0 because dynamic extractors are not supported with payloads yet")
459+
request.Threads = 0
460+
} else {
461+
// specifically for http requests high concurrency and and threads will lead to memory exausthion, hence reduce the maximum parallelism
462+
if protocolstate.IsLowOnMemory() {
463+
request.Threads = protocolstate.GuardThreadsOrDefault(request.Threads)
464+
}
447465
request.Threads = options.GetThreadsForNPayloadRequests(request.Requests(), request.Threads)
448466
}
449467
}
@@ -472,11 +490,3 @@ func (request *Request) Requests() int {
472490
}
473491
return len(request.Path)
474492
}
475-
476-
// PayloadAutoConcurrencyThreshold is the threshold for auto adjusting concurrency
477-
// for payloads in a template.
478-
var PayloadAutoConcurrencyThreshold int
479-
480-
func init() {
481-
PayloadAutoConcurrencyThreshold = env.GetEnvOrDefault[int]("NUCLEI_PAYLOAD_AUTO_CONCURRENCY_THRESHOLD", 100)
482-
}

0 commit comments

Comments
 (0)