Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/input/transform.go
2070 views
1
package input
2
3
import (
4
"net"
5
"path/filepath"
6
"strings"
7
8
"github.com/projectdiscovery/hmap/store/hybrid"
9
templateTypes "github.com/projectdiscovery/nuclei/v3/pkg/templates/types"
10
fileutil "github.com/projectdiscovery/utils/file"
11
"github.com/projectdiscovery/utils/ports"
12
stringsutil "github.com/projectdiscovery/utils/strings"
13
urlutil "github.com/projectdiscovery/utils/url"
14
)
15
16
// Helper is a structure for helping with input transformation
17
type Helper struct {
18
InputsHTTP *hybrid.HybridMap
19
}
20
21
// NewHelper returns a new input helper instance
22
func NewHelper() *Helper {
23
helper := &Helper{}
24
return helper
25
}
26
27
// Close closes the resources associated with input helper
28
func (h *Helper) Close() error {
29
var err error
30
if h.InputsHTTP != nil {
31
err = h.InputsHTTP.Close()
32
}
33
return err
34
}
35
36
// Transform transforms an input based on protocol type and returns
37
// appropriate input based on it.
38
func (h *Helper) Transform(input string, protocol templateTypes.ProtocolType) string {
39
switch protocol {
40
case templateTypes.DNSProtocol, templateTypes.WHOISProtocol:
41
return h.convertInputToType(input, typeHostOnly, "")
42
case templateTypes.FileProtocol, templateTypes.OfflineHTTPProtocol:
43
return h.convertInputToType(input, typeFilepath, "")
44
case templateTypes.HTTPProtocol, templateTypes.HeadlessProtocol:
45
return h.convertInputToType(input, typeURL, "")
46
case templateTypes.NetworkProtocol:
47
return h.convertInputToType(input, typeHostWithOptionalPort, "")
48
case templateTypes.WebsocketProtocol:
49
return h.convertInputToType(input, typeWebsocket, "")
50
case templateTypes.SSLProtocol:
51
return h.convertInputToType(input, typeHostWithPort, "443")
52
}
53
return input
54
}
55
56
type inputType int
57
58
const (
59
typeHostOnly inputType = iota + 1
60
typeHostWithPort
61
typeHostWithOptionalPort
62
typeURL
63
typeFilepath
64
typeWebsocket
65
)
66
67
// convertInputToType converts an input based on an inputType.
68
// Various formats are supported for inputs and their transformation
69
func (h *Helper) convertInputToType(input string, inputType inputType, defaultPort string) string {
70
isURL := strings.Contains(input, "://")
71
uri, _ := urlutil.Parse(input)
72
73
var host, port string
74
if isURL && uri != nil {
75
host, port, _ = net.SplitHostPort(uri.Host)
76
} else {
77
host, port, _ = net.SplitHostPort(input)
78
}
79
80
hasHost := host != ""
81
hasPort := ports.IsValid(port)
82
hasDefaultPort := ports.IsValid(defaultPort)
83
84
switch inputType {
85
case typeFilepath:
86
// if it has ports most likely it's not a file
87
if hasPort {
88
return ""
89
}
90
if filepath.IsAbs(input) {
91
return input
92
}
93
if absPath, _ := filepath.Abs(input); absPath != "" && fileutil.FileOrFolderExists(absPath) {
94
return input
95
}
96
if _, err := filepath.Match(input, ""); err != filepath.ErrBadPattern && !isURL {
97
return input
98
}
99
// if none of these satisfy the condition return empty
100
return ""
101
case typeHostOnly:
102
if hasHost {
103
return host
104
}
105
if isURL && uri != nil {
106
return uri.Hostname()
107
}
108
return input
109
case typeURL:
110
if uri != nil && stringsutil.EqualFoldAny(uri.Scheme, "http", "https") {
111
return input
112
}
113
if h.InputsHTTP != nil {
114
if probed, ok := h.InputsHTTP.Get(input); ok {
115
return string(probed)
116
}
117
}
118
// try to parse it as absolute url and return
119
if absUrl, err := urlutil.ParseAbsoluteURL(input, false); err == nil {
120
return absUrl.String()
121
}
122
case typeHostWithPort, typeHostWithOptionalPort:
123
if hasHost && hasPort {
124
return net.JoinHostPort(host, port)
125
}
126
if uri != nil && !hasPort && uri.Scheme == "https" {
127
return net.JoinHostPort(uri.Host, "443")
128
}
129
if hasDefaultPort {
130
return net.JoinHostPort(input, defaultPort)
131
}
132
if inputType == typeHostWithOptionalPort {
133
return input
134
}
135
case typeWebsocket:
136
if uri != nil && stringsutil.EqualFoldAny(uri.Scheme, "ws", "wss") {
137
return input
138
}
139
// empty if prefix is not given
140
return ""
141
}
142
// do not return empty
143
return input
144
}
145
146