mirror of
https://github.com/projectdiscovery/nuclei
synced 2026-06-08 16:50:47 +00:00
a2a27e57b7
when creating default limiter. The engine could be set up with custom rate limits through `WithOptions()`, but internal was still hardcoding `e.rateLimiter` to 150 RPS when no global limiter was explicitly set. Now it builds the default limiter from the resolved options: 1. Applies `RateLimitMinute` translation, 2. Defaults `RateLimitDuration` to 1s when `RateLimit > 0` and no duration is given, then 3. Creates the limiter via `GetRateLimiter()`. Fixes #7341 Signed-off-by: Dwi Siswanto <git@dw1.io>
123 lines
3.5 KiB
Go
123 lines
3.5 KiB
Go
package nuclei_test
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
nuclei "github.com/projectdiscovery/nuclei/v3/lib"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/types"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestContextCancelNucleiEngine(t *testing.T) {
|
|
// create nuclei engine with options
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
ne, err := nuclei.NewNucleiEngineCtx(ctx,
|
|
nuclei.WithTemplateFilters(nuclei.TemplateFilters{Tags: []string{"oast"}}),
|
|
nuclei.EnableStatsWithOpts(nuclei.StatsOptions{MetricServerPort: 0}),
|
|
)
|
|
require.NoError(t, err, "could not create nuclei engine")
|
|
|
|
go func() {
|
|
time.Sleep(time.Second * 2)
|
|
cancel()
|
|
log.Println("Test: context cancelled")
|
|
}()
|
|
|
|
// load targets and optionally probe non http/https targets
|
|
ne.LoadTargets([]string{"http://honey.scanme.sh"}, false)
|
|
// when callback is nil it nuclei will print JSON output to stdout
|
|
err = ne.ExecuteWithCallback(nil)
|
|
if err != nil {
|
|
// we expect a context cancellation error
|
|
require.ErrorIs(t, err, context.Canceled, "was expecting context cancellation error")
|
|
}
|
|
defer ne.Close()
|
|
}
|
|
|
|
func TestHeadlessOptionInitialization(t *testing.T) {
|
|
ne, err := nuclei.NewNucleiEngineCtx(
|
|
context.Background(),
|
|
nuclei.EnableHeadlessWithOpts(&nuclei.HeadlessOpts{
|
|
PageTimeout: 20,
|
|
ShowBrowser: false,
|
|
UseChrome: false,
|
|
HeadlessOptions: []string{},
|
|
}),
|
|
)
|
|
|
|
require.NoError(t, err, "could not create nuclei engine with headless options")
|
|
require.NotNil(t, ne, "nuclei engine should not be nil")
|
|
|
|
// Verify logger is initialized
|
|
require.NotNil(t, ne.Logger, "logger should be initialized")
|
|
|
|
defer ne.Close()
|
|
}
|
|
|
|
func TestThreadSafeNucleiEngineWithNoHostErrors(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "nuclei-test-no-host-errors-*")
|
|
require.NoError(t, err)
|
|
|
|
tempTemplate, err := os.CreateTemp(tmpDir, "thread-safe-no-host-errors.*.yaml")
|
|
require.NoError(t, err)
|
|
|
|
_, err = tempTemplate.WriteString(`id: thread-safe-no-host-errors
|
|
info:
|
|
name: Thread Safe (NoHostErrors)
|
|
author: nuclei-sdk-test
|
|
severity: info
|
|
http:
|
|
- method: GET
|
|
path:
|
|
- "{{BaseURL}}/"
|
|
matchers:
|
|
- type: word
|
|
words:
|
|
- "ok"`)
|
|
require.NoError(t, err)
|
|
require.NoError(t, tempTemplate.Close())
|
|
|
|
options := types.DefaultOptions().Copy()
|
|
options.NoHostErrors = true
|
|
options.Timeout = 2
|
|
options.Retries = 0
|
|
options.BulkSize = 1
|
|
options.TemplateThreads = 1
|
|
options.Templates = append(options.Templates, tempTemplate.Name())
|
|
|
|
ne, err := nuclei.NewThreadSafeNucleiEngineCtx(context.TODO(), nuclei.WithOptions(options))
|
|
require.NoError(t, err, "could not create nuclei engine")
|
|
|
|
defer func() {
|
|
ne.Close()
|
|
_ = os.RemoveAll(tmpDir)
|
|
}()
|
|
|
|
err = ne.GlobalLoadAllTemplates()
|
|
require.NoError(t, err, "could not load templates")
|
|
|
|
err = ne.ExecuteNucleiWithOptsCtx(context.TODO(), []string{"scanme.sh"})
|
|
require.NoError(t, err, "nuclei execution should not return an error")
|
|
}
|
|
|
|
func TestWithOptionsRateLimitSetsRuntimeLimiter(t *testing.T) {
|
|
opts := types.DefaultOptions().Copy()
|
|
opts.RateLimit = 500
|
|
opts.RateLimitDuration = time.Second
|
|
|
|
ne, err := nuclei.NewNucleiEngineCtx(context.Background(), nuclei.WithOptions(opts))
|
|
require.NoError(t, err, "could not create nuclei engine")
|
|
t.Cleanup(func() {
|
|
ne.Close()
|
|
})
|
|
|
|
execOpts := ne.GetExecuterOptions()
|
|
require.NotNil(t, execOpts, "executor options should be initialized")
|
|
require.NotNil(t, execOpts.RateLimiter, "rate limiter should be initialized")
|
|
require.Equal(t, opts.RateLimit, int(execOpts.RateLimiter.GetLimit()), "runtime limiter should match rate limit from WithOptions")
|
|
}
|