From 39c89344a023a1547983e7a07a40b05ffd387990 Mon Sep 17 00:00:00 2001 From: DoI <5291556+denandz@users.noreply.github.com> Date: Fri, 3 Feb 2023 20:09:29 +1300 Subject: [PATCH] Added additional proxy URL verification (#574) * Added additional proxy URL verification * Update pkg/ffuf/optionsparser.go Co-authored-by: Joona Hoikkala --------- Co-authored-by: Joona Hoikkala --- pkg/ffuf/optionsparser.go | 12 ++--- pkg/ffuf/optionsparser_test.go | 95 ++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 6 deletions(-) diff --git a/pkg/ffuf/optionsparser.go b/pkg/ffuf/optionsparser.go index 7df672c..277ad58 100644 --- a/pkg/ffuf/optionsparser.go +++ b/pkg/ffuf/optionsparser.go @@ -374,9 +374,9 @@ func ConfigFromOptions(parseOpts *ConfigOptions, ctx context.Context, cancel con // Verify proxy url format if len(parseOpts.HTTP.ProxyURL) > 0 { - _, err := url.Parse(parseOpts.HTTP.ProxyURL) - if err != nil { - errs.Add(fmt.Errorf("Bad proxy url (-x) format: %s", err)) + u, err := url.Parse(parseOpts.HTTP.ProxyURL) + if err != nil || u.Opaque != "" || (u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "socks5") { + errs.Add(fmt.Errorf("Bad proxy url (-x) format. Expected http, https or socks5 url")) } else { conf.ProxyURL = parseOpts.HTTP.ProxyURL } @@ -384,9 +384,9 @@ func ConfigFromOptions(parseOpts *ConfigOptions, ctx context.Context, cancel con // Verify replayproxy url format if len(parseOpts.HTTP.ReplayProxyURL) > 0 { - _, err := url.Parse(parseOpts.HTTP.ReplayProxyURL) - if err != nil { - errs.Add(fmt.Errorf("Bad replay-proxy url (-replay-proxy) format: %s", err)) + u, err := url.Parse(parseOpts.HTTP.ReplayProxyURL) + if err != nil || u.Opaque != "" || (u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "socks5" && u.Scheme != "socks5h") { + errs.Add(fmt.Errorf("Bad replay-proxy url (-replay-proxy) format. Expected http, https or socks5 url")) } else { conf.ReplayProxyURL = parseOpts.HTTP.ReplayProxyURL } diff --git a/pkg/ffuf/optionsparser_test.go b/pkg/ffuf/optionsparser_test.go index 2e9913b..2ed741f 100644 --- a/pkg/ffuf/optionsparser_test.go +++ b/pkg/ffuf/optionsparser_test.go @@ -1,6 +1,7 @@ package ffuf import ( + "strings" "testing" ) @@ -83,3 +84,97 @@ func TestTemplatePresent(t *testing.T) { t.Errorf("Expected-bad config (Header key) failed validation") } } + +func TestProxyParsing(t *testing.T) { + configOptions := NewConfigOptions() + errorString := "Bad proxy url (-x) format. Expected http, https or socks5 url" + + // http should work + configOptions.HTTP.ProxyURL = "http://127.0.0.1:8080" + _, err := ConfigFromOptions(configOptions, nil, nil) + if strings.Contains(err.Error(), errorString) { + t.Errorf("Expected http proxy string to work") + } + + // https should work + configOptions.HTTP.ProxyURL = "https://127.0.0.1" + _, err = ConfigFromOptions(configOptions, nil, nil) + if strings.Contains(err.Error(), errorString) { + t.Errorf("Expected https proxy string to work") + } + + // socks5 should work + configOptions.HTTP.ProxyURL = "socks5://127.0.0.1" + _, err = ConfigFromOptions(configOptions, nil, nil) + if strings.Contains(err.Error(), errorString) { + t.Errorf("Expected socks5 proxy string to work") + } + + // garbage data should FAIL + configOptions.HTTP.ProxyURL = "Y0 y0 it's GREASE" + _, err = ConfigFromOptions(configOptions, nil, nil) + if !strings.Contains(err.Error(), errorString) { + t.Errorf("Expected garbage proxy string to fail") + } + + // Opaque URLs with the right scheme should FAIL + configOptions.HTTP.ProxyURL = "http:sixhours@dungeon" + _, err = ConfigFromOptions(configOptions, nil, nil) + if !strings.Contains(err.Error(), errorString) { + t.Errorf("Expected opaque proxy string to fail") + } + + // Unsupported protocols should FAIL + configOptions.HTTP.ProxyURL = "imap://127.0.0.1" + _, err = ConfigFromOptions(configOptions, nil, nil) + if !strings.Contains(err.Error(), errorString) { + t.Errorf("Expected proxy string with unsupported protocol to fail") + } +} + +func TestReplayProxyParsing(t *testing.T) { + configOptions := NewConfigOptions() + errorString := "Bad replay-proxy url (-replay-proxy) format. Expected http, https or socks5 url" + + // http should work + configOptions.HTTP.ReplayProxyURL = "http://127.0.0.1:8080" + _, err := ConfigFromOptions(configOptions, nil, nil) + if strings.Contains(err.Error(), errorString) { + t.Errorf("Expected http replay proxy string to work") + } + + // https should work + configOptions.HTTP.ReplayProxyURL = "https://127.0.0.1" + _, err = ConfigFromOptions(configOptions, nil, nil) + if strings.Contains(err.Error(), errorString) { + t.Errorf("Expected https proxy string to work") + } + + // socks5 should work + configOptions.HTTP.ReplayProxyURL = "socks5://127.0.0.1" + _, err = ConfigFromOptions(configOptions, nil, nil) + if strings.Contains(err.Error(), errorString) { + t.Errorf("Expected socks5 proxy string to work") + } + + // garbage data should FAIL + configOptions.HTTP.ReplayProxyURL = "Y0 y0 it's GREASE" + _, err = ConfigFromOptions(configOptions, nil, nil) + if !strings.Contains(err.Error(), errorString) { + t.Errorf("Expected garbage proxy string to fail") + } + + // Opaque URLs with the right scheme should FAIL + configOptions.HTTP.ReplayProxyURL = "http:sixhours@dungeon" + _, err = ConfigFromOptions(configOptions, nil, nil) + if !strings.Contains(err.Error(), errorString) { + t.Errorf("Expected opaque proxy string to fail") + } + + // Unsupported protocols should FAIL + configOptions.HTTP.ReplayProxyURL = "imap://127.0.0.1" + _, err = ConfigFromOptions(configOptions, nil, nil) + if !strings.Contains(err.Error(), errorString) { + t.Errorf("Expected proxy string with unsupported protocol to fail") + } +}