mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-18 16:07:23 +00:00
Merge pull request #697 from projectdiscovery/bugfix-host-header
Better host header handling in RFC compliant requests
This commit is contained in:
commit
31fc50d2a5
@ -164,6 +164,9 @@ func (r *requestGenerator) handleRawWithPayloads(ctx context.Context, rawRequest
|
||||
continue
|
||||
}
|
||||
req.Header[key] = []string{value}
|
||||
if key == "Host" {
|
||||
req.Host = value
|
||||
}
|
||||
}
|
||||
request, err := r.fillRequest(req, values, "")
|
||||
if err != nil {
|
||||
@ -181,6 +184,9 @@ func (r *requestGenerator) fillRequest(req *http.Request, values map[string]inte
|
||||
value = r.options.Interactsh.ReplaceMarkers(value, interactURL)
|
||||
}
|
||||
req.Header[header] = []string{replacer.Replace(value, values)}
|
||||
if header == "Host" {
|
||||
req.Host = replacer.Replace(value, values)
|
||||
}
|
||||
}
|
||||
|
||||
// In case of multiple threads the underlying connection should remain open to allow reuse
|
||||
@ -211,4 +217,7 @@ func setHeader(req *http.Request, name, value string) {
|
||||
if _, ok := req.Header[name]; !ok {
|
||||
req.Header.Set(name, value)
|
||||
}
|
||||
if name == "Host" {
|
||||
req.Host = value
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
@ -100,20 +99,11 @@ func Parse(request, baseURL string, unsafe bool) (*Request, error) {
|
||||
rawRequest.Path = parts[1]
|
||||
}
|
||||
|
||||
// If raw request doesn't have a Host header and/ path,
|
||||
// this will be generated from the parsed baseURL
|
||||
parsedURL, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse request URL: %s", err)
|
||||
}
|
||||
|
||||
templateHost := rawRequest.Headers["Host"]
|
||||
hostURL := parsedURL.Host
|
||||
|
||||
if strings.Contains(templateHost, ":") {
|
||||
_, templatePort, _ := net.SplitHostPort(templateHost)
|
||||
hostURL = net.JoinHostPort(parsedURL.Hostname(), templatePort)
|
||||
}
|
||||
if strings.HasSuffix(parsedURL.Path, "/") && strings.HasPrefix(rawRequest.Path, "/") {
|
||||
parsedURL.Path = strings.TrimSuffix(parsedURL.Path, "/")
|
||||
}
|
||||
@ -123,6 +113,12 @@ func Parse(request, baseURL string, unsafe bool) (*Request, error) {
|
||||
}
|
||||
rawRequest.FullURL = fmt.Sprintf("%s://%s%s", parsedURL.Scheme, strings.TrimSpace(hostURL), rawRequest.Path)
|
||||
|
||||
// If raw request doesn't have a Host header
|
||||
// this will be generated from the parsed baseURL
|
||||
if rawRequest.Headers["Host"] == "" {
|
||||
rawRequest.Headers["Host"] = hostURL
|
||||
}
|
||||
|
||||
// Set the request body
|
||||
b, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
|
||||
@ -15,7 +15,7 @@ User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (
|
||||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
|
||||
Accept-Language: en-US,en;q=0.9`, "https://example.com:8080", false)
|
||||
require.Nil(t, err, "could not parse GET request")
|
||||
require.Equal(t, "https://example.com:123/gg/phpinfo.php", request.FullURL, "Could not parse request url correctly")
|
||||
require.Equal(t, "https://example.com:8080/gg/phpinfo.php", request.FullURL, "Could not parse request url correctly")
|
||||
require.Equal(t, "/gg/phpinfo.php", request.Path, "Could not parse request path correctly")
|
||||
|
||||
t.Run("path-suffix", func(t *testing.T) {
|
||||
@ -29,17 +29,17 @@ Host: {{Hostname}}`, "https://example.com:8080/test", false)
|
||||
request, err := Parse(`GET ?username=test&password=test HTTP/1.1
|
||||
Host: {{Hostname}}:123`, "https://example.com:8080/test", false)
|
||||
require.Nil(t, err, "could not parse GET request")
|
||||
require.Equal(t, "https://example.com:123/test?username=test&password=test", request.FullURL, "Could not parse request url correctly")
|
||||
require.Equal(t, "https://example.com:8080/test?username=test&password=test", request.FullURL, "Could not parse request url correctly")
|
||||
|
||||
request, err = Parse(`GET ?username=test&password=test HTTP/1.1
|
||||
Host: {{Hostname}}:123`, "https://example.com:8080/test/", false)
|
||||
require.Nil(t, err, "could not parse GET request")
|
||||
require.Equal(t, "https://example.com:123/test/?username=test&password=test", request.FullURL, "Could not parse request url correctly")
|
||||
require.Equal(t, "https://example.com:8080/test/?username=test&password=test", request.FullURL, "Could not parse request url correctly")
|
||||
|
||||
request, err = Parse(`GET /?username=test&password=test HTTP/1.1
|
||||
Host: {{Hostname}}:123`, "https://example.com:8080/test/", false)
|
||||
require.Nil(t, err, "could not parse GET request")
|
||||
require.Equal(t, "https://example.com:123/test/?username=test&password=test", request.FullURL, "Could not parse request url correctly")
|
||||
require.Equal(t, "https://example.com:8080/test/?username=test&password=test", request.FullURL, "Could not parse request url correctly")
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -430,7 +430,11 @@ func (r *Request) setCustomHeaders(req *generatedRequest) {
|
||||
if req.rawRequest != nil {
|
||||
req.rawRequest.Headers[k] = v
|
||||
} else {
|
||||
req.request.Header.Set(strings.TrimSpace(k), strings.TrimSpace(v))
|
||||
kk, vv := strings.TrimSpace(k), strings.TrimSpace(v)
|
||||
req.request.Header.Set(kk, vv)
|
||||
if kk == "Host" {
|
||||
req.request.Host = vv
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user