From 3fc2cc247b22f8a2e16618692c771e2c66de630a Mon Sep 17 00:00:00 2001 From: ysokolovsky Date: Mon, 11 Aug 2025 16:10:49 +0300 Subject: [PATCH 1/2] headless: fix extra headers overwrite --- pkg/protocols/headless/engine/engine.go | 35 ++++++++++++++++++++----- pkg/protocols/headless/engine/page.go | 8 +++--- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/pkg/protocols/headless/engine/engine.go b/pkg/protocols/headless/engine/engine.go index 63dbb41ef6..e77c26896a 100644 --- a/pkg/protocols/headless/engine/engine.go +++ b/pkg/protocols/headless/engine/engine.go @@ -20,12 +20,13 @@ import ( // Browser is a browser structure for nuclei headless module type Browser struct { - customAgent string - tempDir string - previousPIDs map[int32]struct{} // track already running PIDs - engine *rod.Browser - options *types.Options - launcher *launcher.Launcher + customAgent string + defaultHeaders map[string]string + tempDir string + previousPIDs map[int32]struct{} // track already running PIDs + engine *rod.Browser + options *types.Options + launcher *launcher.Launcher // use getHTTPClient to get the http client httpClient *http.Client @@ -95,6 +96,7 @@ func New(options *types.Options) (*Browser, error) { if browserErr := browser.Connect(); browserErr != nil { return nil, browserErr } + defaultHeaders := make(map[string]string) customAgent := "" for _, option := range options.CustomHeaders { parts := strings.SplitN(option, ":", 2) @@ -103,12 +105,20 @@ func New(options *types.Options) (*Browser, error) { } if strings.EqualFold(parts[0], "User-Agent") { customAgent = parts[1] + } else { + k := strings.TrimSpace(parts[0]) + v := strings.TrimSpace(parts[1]) + if k == "" || v == "" { + continue + } + defaultHeaders[k] = v } } engine := &Browser{ tempDir: dataStore, customAgent: customAgent, + defaultHeaders: defaultHeaders, engine: browser, options: options, httpClientOnce: &sync.Once{}, @@ -135,6 +145,19 @@ func (b *Browser) UserAgent() string { return b.customAgent } +func (b *Browser) applyDefaultHeaders(p *rod.Page) error { + if len(b.defaultHeaders) == 0 { + return nil + } + pairs := make([]string, 0, len(b.defaultHeaders)*2) + pairs = append(pairs, "Accept-Language", "en, en-GB, en-us;") + for k, v := range b.defaultHeaders { + pairs = append(pairs, k, v) + } + _, err := p.SetExtraHeaders(pairs) + return err +} + func (b *Browser) getHTTPClient() (*http.Client, error) { var err error b.httpClientOnce.Do(func() { diff --git a/pkg/protocols/headless/engine/page.go b/pkg/protocols/headless/engine/page.go index 6986f80b45..244d740c86 100644 --- a/pkg/protocols/headless/engine/page.go +++ b/pkg/protocols/headless/engine/page.go @@ -61,6 +61,10 @@ func (i *Instance) Run(ctx *contextargs.Context, actions []*Action, payloads map } page = page.Timeout(options.Timeout) + if err = i.browser.applyDefaultHeaders(page); err != nil { + return nil, nil, err + } + if i.browser.customAgent != "" { if userAgentErr := page.SetUserAgent(&proto.NetworkSetUserAgentOverride{UserAgent: i.browser.customAgent}); userAgentErr != nil { return nil, nil, userAgentErr @@ -130,10 +134,6 @@ func (i *Instance) Run(ctx *contextargs.Context, actions []*Action, payloads map return nil, nil, err } - if _, err := page.SetExtraHeaders([]string{"Accept-Language", "en, en-GB, en-us;"}); err != nil { - return nil, nil, err - } - // inject cookies // each http request is performed via the native go http client // we first inject the shared cookies From ccc0e01c94baa2f8ac0757f2cd42e97d25a6fa74 Mon Sep 17 00:00:00 2001 From: ysokolovsky Date: Mon, 11 Aug 2025 17:16:08 +0300 Subject: [PATCH 2/2] headless: set Accept-Language when no custom headers --- pkg/protocols/headless/engine/engine.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/protocols/headless/engine/engine.go b/pkg/protocols/headless/engine/engine.go index e77c26896a..9988502376 100644 --- a/pkg/protocols/headless/engine/engine.go +++ b/pkg/protocols/headless/engine/engine.go @@ -145,15 +145,26 @@ func (b *Browser) UserAgent() string { return b.customAgent } +// applyDefaultHeaders setsheaders passed via cli -H flag func (b *Browser) applyDefaultHeaders(p *rod.Page) error { - if len(b.defaultHeaders) == 0 { - return nil + pairs := make([]string, 0, len(b.defaultHeaders)*2+2) + + hasAcceptLanguage := false + for k := range b.defaultHeaders { + if strings.EqualFold(k, "Accept-Language") { + hasAcceptLanguage = true + break + } + } + if !hasAcceptLanguage { + pairs = append(pairs, "Accept-Language", "en, en-GB, en-us;") } - pairs := make([]string, 0, len(b.defaultHeaders)*2) - pairs = append(pairs, "Accept-Language", "en, en-GB, en-us;") for k, v := range b.defaultHeaders { pairs = append(pairs, k, v) } + if len(pairs) == 0 { + return nil + } _, err := p.SetExtraHeaders(pairs) return err }