mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2026-11-10 04:01:31 -10:00
* chore(deps): strip dependencies Signed-off-by: Dwi Siswanto <[email protected]> * chore: drop stripped dependencies Signed-off-by: Dwi Siswanto <[email protected]> * tests(integration): reduce external service flakiness Signed-off-by: Dwi Siswanto <[email protected]> * refactor(types): replace govalidator ASCII check Signed-off-by: Dwi Siswanto <[email protected]> * chore(trackers): update go-github import path Signed-off-by: Dwi Siswanto <[email protected]> * chore: use our PD wrapper Signed-off-by: Dwi Siswanto <[email protected]> * chore: use our PD cache packages Signed-off-by: Dwi Siswanto <[email protected]> * chore(utils): use x/net publicsuffix Signed-off-by: Dwi Siswanto <[email protected]> * chore(input): decode YAML without invopop/yaml Signed-off-by: Dwi Siswanto <[email protected]> * refactor(yaml): route callers through pkg/utils/yaml Signed-off-by: Dwi Siswanto <[email protected]> * refactor(json): route callers through pkg/utils/json Signed-off-by: Dwi Siswanto <[email protected]> * refactpr(scan): replace Echo handlers with net/http Signed-off-by: Dwi Siswanto <[email protected]> * refactor(server): replace Echo with net/http Signed-off-by: Dwi Siswanto <[email protected]> * refactor(fuzzplayground): replace Echo server with net/http Signed-off-by: Dwi Siswanto <[email protected]> * test: update subdomains testdata Signed-off-by: Dwi Siswanto <[email protected]> * chore(yaml): satisfy lints Signed-off-by: Dwi Siswanto <[email protected]> * fix codeql --------- Signed-off-by: Dwi Siswanto <[email protected]> Co-authored-by: Mzack9999 <[email protected]>
207 lines
6.8 KiB
Go
207 lines
6.8 KiB
Go
package utils
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
|
|
urlutil "github.com/projectdiscovery/utils/url"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestHTTPVariables(t *testing.T) {
|
|
baseURL := "http://localhost:9001/test/123"
|
|
parsed, _ := urlutil.Parse(baseURL)
|
|
// trailing slash is only true when both target/inputURL and payload {{BaseURL}}/xyz both have slash
|
|
values := GenerateVariables(parsed, false, nil)
|
|
|
|
require.Equal(t, values["BaseURL"], parsed.String(), "incorrect baseurl")
|
|
require.Equal(t, values["RootURL"], "http://localhost:9001", "incorrect rootURL")
|
|
require.Equal(t, values["Host"], "localhost", "incorrect domain name")
|
|
require.Equal(t, values["Path"], "/test", "incorrect path")
|
|
require.Equal(t, values["File"], "123", "incorrect file")
|
|
require.Equal(t, values["Port"], "9001", "incorrect port number")
|
|
require.Equal(t, values["Scheme"], "http", "incorrect scheme")
|
|
require.Equal(t, values["Hostname"], "localhost:9001", "incorrect hostname")
|
|
|
|
baseURL = "https://example.com"
|
|
parsed, _ = urlutil.Parse(baseURL)
|
|
values = GenerateVariables(parsed, false, nil)
|
|
|
|
require.Equal(t, values["BaseURL"], parsed.String(), "incorrect baseurl")
|
|
require.Equal(t, values["Host"], "example.com", "incorrect domain name")
|
|
require.Equal(t, values["RootURL"], "https://example.com", "incorrect rootURL")
|
|
require.Equal(t, values["Path"], "", "incorrect path")
|
|
require.Equal(t, values["Port"], "443", "incorrect port number")
|
|
require.Equal(t, values["Scheme"], "https", "incorrect scheme")
|
|
require.Equal(t, values["Hostname"], "example.com", "incorrect hostname")
|
|
|
|
baseURL = "ftp://foobar.com/"
|
|
parsed, _ = urlutil.Parse(baseURL)
|
|
values = GenerateVariables(parsed, false, nil)
|
|
|
|
require.Equal(t, values["BaseURL"], parsed.String(), "incorrect baseurl")
|
|
require.Equal(t, values["Host"], "foobar.com", "incorrect domain name")
|
|
require.Equal(t, values["RootURL"], "ftp://foobar.com", "incorrect rootURL")
|
|
require.Equal(t, values["Path"], "/", "incorrect path")
|
|
require.Equal(t, values["Port"], "", "incorrect port number") // Unsupported protocol results in a blank port
|
|
require.Equal(t, values["Scheme"], "ftp", "incorrect scheme")
|
|
require.Equal(t, values["Hostname"], "foobar.com", "incorrect hostname")
|
|
|
|
baseURL = "http://scanme.sh"
|
|
ctxArgs := contextargs.NewWithInput(context.Background(), baseURL)
|
|
ctxArgs.MetaInput.CustomIP = "1.2.3.4"
|
|
values = GenerateVariablesWithContextArgs(ctxArgs, true)
|
|
|
|
require.Equal(t, values["BaseURL"], baseURL, "incorrect baseurl")
|
|
require.Equal(t, values["Host"], "scanme.sh", "incorrect domain name")
|
|
require.Equal(t, values["RootURL"], "http://scanme.sh", "incorrect rootURL")
|
|
require.Equal(t, values["Path"], "", "incorrect path")
|
|
require.Equal(t, values["Port"], "80", "incorrect port number")
|
|
require.Equal(t, values["Scheme"], "http", "incorrect scheme")
|
|
require.Equal(t, values["Hostname"], "scanme.sh", "incorrect hostname")
|
|
require.Equal(t, values["ip"], "1.2.3.4", "incorrect ip")
|
|
}
|
|
|
|
func TestGenerateDNSVariables(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
input string
|
|
expected map[string]interface{}
|
|
}{
|
|
{
|
|
name: "simple domain",
|
|
input: "www.projectdiscovery.io",
|
|
expected: map[string]interface{}{
|
|
"FQDN": "www.projectdiscovery.io",
|
|
"RDN": "projectdiscovery.io",
|
|
"DN": "projectdiscovery",
|
|
"TLD": "io",
|
|
"SD": "www",
|
|
},
|
|
},
|
|
{
|
|
name: "multi label public suffix",
|
|
input: "api.service.example.co.uk",
|
|
expected: map[string]interface{}{
|
|
"FQDN": "api.service.example.co.uk",
|
|
"RDN": "example.co.uk",
|
|
"DN": "example",
|
|
"TLD": "co.uk",
|
|
"SD": "api.service",
|
|
},
|
|
},
|
|
{
|
|
name: "trailing dot",
|
|
input: "www.projectdiscovery.io.",
|
|
expected: map[string]interface{}{
|
|
"FQDN": "www.projectdiscovery.io.",
|
|
"RDN": "projectdiscovery.io",
|
|
"DN": "projectdiscovery",
|
|
"TLD": "io",
|
|
"SD": "www",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, testCase := range testCases {
|
|
t.Run(testCase.name, func(t *testing.T) {
|
|
vars := GenerateDNSVariables(testCase.input)
|
|
require.Equal(t, testCase.expected, vars, "could not get dns variables")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGenerateVariablesForDNS(t *testing.T) {
|
|
vars := GenerateVariables("www.projectdiscovery.io", false, nil)
|
|
expected := map[string]interface{}{
|
|
"FQDN": "www.projectdiscovery.io",
|
|
"RDN": "projectdiscovery.io",
|
|
"DN": "projectdiscovery",
|
|
"TLD": "io",
|
|
"SD": "www",
|
|
}
|
|
checkResults(t, vars, expected)
|
|
}
|
|
|
|
func TestGenerateVariablesForTCP(t *testing.T) {
|
|
vars := GenerateVariables("127.0.0.1:5431", false, nil)
|
|
expected := map[string]interface{}{
|
|
"Host": "127.0.0.1",
|
|
"Port": "5431",
|
|
"Hostname": "127.0.0.1:5431",
|
|
}
|
|
checkResults(t, vars, expected)
|
|
|
|
vars = GenerateVariables("127.0.0.1", false, nil)
|
|
expected = map[string]interface{}{
|
|
"Host": "127.0.0.1",
|
|
"Hostname": "127.0.0.1",
|
|
}
|
|
checkResults(t, vars, expected)
|
|
}
|
|
|
|
func TestGenerateWhoISVariables(t *testing.T) {
|
|
vars := GenerateVariables("https://example.com", false, nil)
|
|
expected := map[string]interface{}{
|
|
"Host": "example.com", "Hostname": "example.com", "Input": "https://example.com",
|
|
}
|
|
checkResults(t, vars, expected)
|
|
|
|
vars = GenerateVariables("https://example.com:8080", false, nil)
|
|
expected = map[string]interface{}{
|
|
"Host": "example.com", "Hostname": "example.com:8080", "Input": "https://example.com:8080",
|
|
}
|
|
checkResults(t, vars, expected)
|
|
}
|
|
|
|
func TestGetWebsocketVariables(t *testing.T) {
|
|
baseURL := "ws://127.0.0.1:40221"
|
|
parsed, _ := urlutil.Parse(baseURL)
|
|
vars := GenerateVariables(parsed, false, nil)
|
|
expected := map[string]interface{}{
|
|
"Host": "127.0.0.1",
|
|
"Hostname": "127.0.0.1:40221",
|
|
"Scheme": "ws",
|
|
"Path": "",
|
|
}
|
|
checkResults(t, vars, expected)
|
|
|
|
baseURL = "ws://127.0.0.1:40221/test?var=test"
|
|
parsed, _ = urlutil.Parse(baseURL)
|
|
vars = GenerateVariables(parsed, false, nil)
|
|
expected = map[string]interface{}{
|
|
"Host": "127.0.0.1",
|
|
"Hostname": "127.0.0.1:40221",
|
|
"Scheme": "ws",
|
|
"Path": "/test?var=test",
|
|
}
|
|
checkResults(t, vars, expected)
|
|
}
|
|
|
|
// checkResults returns true if mapSubset is a subset of mapSet otherwise false
|
|
func checkResults(t *testing.T, mapSet interface{}, mapSubset interface{}) {
|
|
|
|
got := reflect.ValueOf(mapSet)
|
|
expected := reflect.ValueOf(mapSubset)
|
|
|
|
require.Greater(t, len(expected.MapKeys()), 0, "failed expected value is empty")
|
|
require.Greater(t, len(got.MapKeys()), 0, "failed expected value is empty")
|
|
|
|
require.LessOrEqual(t, len(expected.MapKeys()), len(got.MapKeys()), "failed return value more than expected")
|
|
|
|
iterMapSubset := expected.MapRange()
|
|
|
|
for iterMapSubset.Next() {
|
|
k := iterMapSubset.Key()
|
|
v := iterMapSubset.Value()
|
|
|
|
value := got.MapIndex(k)
|
|
|
|
if !value.IsValid() || v.Interface() != value.Interface() {
|
|
require.Equal(t, value, v, "failed return value is not equal to expected")
|
|
}
|
|
}
|
|
}
|