mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2026-11-07 09:46:03 -10:00
fix(cmd): keep "#" in -H header values
Signed-off-by: anant <[email protected]>
This commit is contained in:
1 parent
d465cc82a4
commit
7748411200
2 files changed
+74
-1
No files matched your search
@@ -0,0 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/projectdiscovery/gologger"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const headerChildEnv = "NUCLEI_HEADER_CHILD_ARGS"
|
||||
|
||||
// -H values can contain "#", on the command line, in a header file and in the
|
||||
// config file, while lines of a header file that start with "#" are skipped as
|
||||
// comments.
|
||||
func TestHeaderValuesKeepHash(t *testing.T) {
|
||||
if args := os.Getenv(headerChildEnv); args != "" {
|
||||
options = &types.Options{Logger: gologger.DefaultLogger}
|
||||
os.Args = append([]string{os.Args[0]}, strings.Split(args, "\n")...)
|
||||
readConfig()
|
||||
fmt.Printf("headers=%s\n", strings.Join(options.CustomHeaders, "|"))
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
root := t.TempDir()
|
||||
headerFile := filepath.Join(root, "headers.txt")
|
||||
require.NoError(t, os.WriteFile(headerFile, []byte("# auth headers\nX-Token: abc#def\nReferer: https://app.example.com/#/dashboard\n"), 0o600))
|
||||
configFile := filepath.Join(root, "config.yaml")
|
||||
require.NoError(t, os.WriteFile(configFile, []byte("header:\n - \"X-Config: cfg#value\"\n"), 0o600))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
want string
|
||||
}{
|
||||
{"cli and header file", []string{"-H", "Cookie: sid=1; color=#ff0000", "-H", headerFile}, "Cookie: sid=1; color=#ff0000|X-Token: abc#def|Referer: https://app.example.com/#/dashboard"},
|
||||
{"config file", []string{"-config", configFile}, "X-Config: cfg#value"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tempRoot := filepath.Join(t.TempDir(), "tmp")
|
||||
require.NoError(t, os.Mkdir(tempRoot, 0o700))
|
||||
|
||||
args := append(tt.args, "-disable-update-check")
|
||||
cmd := exec.Command(os.Args[0], "-test.run=^TestHeaderValuesKeepHash$", "-test.count=1")
|
||||
cmd.Env = isolatedNucleiStorageEnv(root, tempRoot, headerChildEnv+"="+strings.Join(args, "\n"))
|
||||
output, err := cmd.CombinedOutput()
|
||||
require.NoError(t, err, string(output))
|
||||
require.Contains(t, string(output), "headers="+tt.want+"\n")
|
||||
})
|
||||
}
|
||||
}
|
||||
+17
-1
@@ -55,6 +55,17 @@ var (
|
||||
inlineSecretsTempMu sync.Mutex
|
||||
)
|
||||
|
||||
// normalizeHeaderValue trims a -H value and drops it when the whole line is a
|
||||
// "#" comment. The goflags default strips inline comments, which cut values
|
||||
// such as "Cookie: color=#fff" at the "#".
|
||||
func normalizeHeaderValue(s string) string {
|
||||
s = strings.TrimSpace(s)
|
||||
if strings.HasPrefix(s, "#") {
|
||||
return ""
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func main() {
|
||||
options.Logger = gologger.DefaultLogger
|
||||
|
||||
@@ -255,6 +266,11 @@ func readConfig() *goflags.FlagSet {
|
||||
var pdcpAuth string
|
||||
var fuzzFlag bool
|
||||
|
||||
// FileStringSliceOptions as set up by runner.ConfigureOptions, but keeping
|
||||
// "#" inside -H values
|
||||
headerSliceOptions := goflags.FileStringSliceOptions
|
||||
headerSliceOptions.Normalize = normalizeHeaderValue
|
||||
|
||||
flagSet := goflags.NewFlagSet()
|
||||
flagSet.CaseSensitive = true
|
||||
flagSet.SetDescription(`Nuclei is a fast, template based vulnerability scanner focusing
|
||||
@@ -367,7 +383,7 @@ on extensive configurability, massive extensibility and ease of use.`)
|
||||
flagSet.IntVarP(&options.MaxRedirects, "max-redirects", "mr", 10, "max number of redirects to follow for http templates"),
|
||||
flagSet.BoolVarP(&options.DisableRedirects, "disable-redirects", "dr", false, "disable redirects for http templates"),
|
||||
flagSet.StringVarP(&options.ReportingConfig, "report-config", "rc", "", "nuclei reporting module configuration file"), // TODO merge into the config file or rename to issue-tracking
|
||||
flagSet.StringSliceVarP(&options.CustomHeaders, "header", "H", nil, "custom header/cookie to include in all http request in header:value format (cli, file)", goflags.FileStringSliceOptions),
|
||||
flagSet.StringSliceVarP(&options.CustomHeaders, "header", "H", nil, "custom header/cookie to include in all http request in header:value format (cli, file)", headerSliceOptions),
|
||||
flagSet.RuntimeMapVarP(&options.Vars, "var", "V", nil, "custom vars in key=value format"),
|
||||
flagSet.StringVarP(&options.ResolversFile, "resolvers", "r", "", "file containing resolver list for nuclei"),
|
||||
flagSet.BoolVarP(&options.SystemResolvers, "system-resolvers", "sr", false, "use system DNS resolving as error fallback"),
|
||||
|
||||
Reference in new issue
Block a user