Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 42 additions & 6 deletions pkg/protocols/utils/fields.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package utils

import (
"net"
"strings"

"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
iputil "github.com/projectdiscovery/utils/ip"
urlutil "github.com/projectdiscovery/utils/url"
Expand Down Expand Up @@ -28,17 +31,21 @@ func GetJsonFieldsFromURL(URL string) JsonFields {
URL: parsed.String(),
Path: parsed.Path,
}

host := parsed.Host
host, fields.Port = extractHostPort(host, fields.Port)

if fields.Port == "" {
fields.Port = "80"
if fields.Scheme == "https" {
fields.Port = "443"
}
}
if iputil.IsIP(parsed.Host) {
fields.Ip = parsed.Host
if iputil.IsIP(host) {
fields.Ip = host
}

fields.Host = parsed.Host
fields.Host = host
return fields
}

Expand All @@ -56,16 +63,45 @@ func GetJsonFieldsFromMetaInput(ctx *contextargs.MetaInput) JsonFields {
fields.Scheme = parsed.Scheme
fields.URL = parsed.String()
fields.Path = parsed.Path

host := parsed.Host
host, fields.Port = extractHostPort(host, fields.Port)

if fields.Port == "" {
fields.Port = "80"
if fields.Scheme == "https" {
fields.Port = "443"
}
}
if iputil.IsIP(parsed.Host) {
fields.Ip = parsed.Host
if iputil.IsIP(host) {
fields.Ip = host
}

fields.Host = parsed.Host
fields.Host = host
return fields
}

func extractHostPort(host, port string) (string, string) {
if !strings.Contains(host, ":") {
return host, port
}
if strings.HasPrefix(host, "[") {
if idx := strings.Index(host, "]:"); idx != -1 {
if port == "" {
port = host[idx+2:]
}
return host[1:idx], port
}
if strings.HasSuffix(host, "]") {
return host[1 : len(host)-1], port
}
return host, port
}
if h, p, err := net.SplitHostPort(host); err == nil {
if port == "" {
port = p
}
return h, port
}
return host, port
}
138 changes: 138 additions & 0 deletions pkg/protocols/utils/fields_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package utils

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestGetJsonFieldsFromURL_HostPortExtraction(t *testing.T) {
t.Parallel()

tests := []struct {
name string
input string
expectedHost string
expectedPort string
}{
{
name: "URL with scheme and port",
input: "http://example.com:8080/path",
expectedHost: "example.com",
expectedPort: "8080",
},
{
name: "URL with scheme no port",
input: "https://example.com/path",
expectedHost: "example.com",
expectedPort: "443",
},
{
name: "host:port without scheme",
input: "example.com:8080",
expectedHost: "example.com",
expectedPort: "8080",
},
{
name: "host:port with standard HTTPS port",
input: "example.com:443",
expectedHost: "example.com",
expectedPort: "443",
},
{
name: "IPv4 with port",
input: "192.168.1.1:8080",
expectedHost: "192.168.1.1",
expectedPort: "8080",
},
{
name: "IPv6 with port",
input: "[2001:db8::1]:8080",
expectedHost: "2001:db8::1",
expectedPort: "8080",
},
{
name: "localhost with port",
input: "localhost:3000",
expectedHost: "localhost",
expectedPort: "3000",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

fields := GetJsonFieldsFromURL(tt.input)

assert.Equal(t, tt.expectedHost, fields.Host)
assert.Equal(t, tt.expectedPort, fields.Port)
})
}
}

func TestExtractHostPort(t *testing.T) {
t.Parallel()

tests := []struct {
name string
host string
port string
expectedHost string
expectedPort string
}{
{
name: "host without port",
host: "example.com",
port: "",
expectedHost: "example.com",
expectedPort: "",
},
{
name: "host with port",
host: "example.com:8080",
port: "",
expectedHost: "example.com",
expectedPort: "8080",
},
{
name: "port already set",
host: "example.com:8080",
port: "443",
expectedHost: "example.com",
expectedPort: "443",
},
{
name: "IPv6 with port",
host: "[::1]:8080",
port: "",
expectedHost: "::1",
expectedPort: "8080",
},
{
name: "IPv6 without port",
host: "[::1]",
port: "",
expectedHost: "::1",
expectedPort: "",
},
{
name: "IPv4 with port",
host: "192.168.1.1:8080",
port: "",
expectedHost: "192.168.1.1",
expectedPort: "8080",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

host, port := extractHostPort(tt.host, tt.port)

assert.Equal(t, tt.expectedHost, host)
assert.Equal(t, tt.expectedPort, port)
})
}
}
Loading