mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-18 14:15:26 +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
|
continue
|
||||||
}
|
}
|
||||||
req.Header[key] = []string{value}
|
req.Header[key] = []string{value}
|
||||||
|
if key == "Host" {
|
||||||
|
req.Host = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
request, err := r.fillRequest(req, values, "")
|
request, err := r.fillRequest(req, values, "")
|
||||||
if err != nil {
|
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)
|
value = r.options.Interactsh.ReplaceMarkers(value, interactURL)
|
||||||
}
|
}
|
||||||
req.Header[header] = []string{replacer.Replace(value, values)}
|
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
|
// 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 {
|
if _, ok := req.Header[name]; !ok {
|
||||||
req.Header.Set(name, value)
|
req.Header.Set(name, value)
|
||||||
}
|
}
|
||||||
|
if name == "Host" {
|
||||||
|
req.Host = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -100,20 +99,11 @@ func Parse(request, baseURL string, unsafe bool) (*Request, error) {
|
|||||||
rawRequest.Path = parts[1]
|
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)
|
parsedURL, err := url.Parse(baseURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not parse request URL: %s", err)
|
return nil, fmt.Errorf("could not parse request URL: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
templateHost := rawRequest.Headers["Host"]
|
|
||||||
hostURL := parsedURL.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, "/") {
|
if strings.HasSuffix(parsedURL.Path, "/") && strings.HasPrefix(rawRequest.Path, "/") {
|
||||||
parsedURL.Path = strings.TrimSuffix(parsedURL.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)
|
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
|
// Set the request body
|
||||||
b, err := ioutil.ReadAll(reader)
|
b, err := ioutil.ReadAll(reader)
|
||||||
if err != nil {
|
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: 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)
|
Accept-Language: en-US,en;q=0.9`, "https://example.com:8080", false)
|
||||||
require.Nil(t, err, "could not parse GET request")
|
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")
|
require.Equal(t, "/gg/phpinfo.php", request.Path, "Could not parse request path correctly")
|
||||||
|
|
||||||
t.Run("path-suffix", func(t *testing.T) {
|
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
|
request, err := Parse(`GET ?username=test&password=test HTTP/1.1
|
||||||
Host: {{Hostname}}:123`, "https://example.com:8080/test", false)
|
Host: {{Hostname}}:123`, "https://example.com:8080/test", false)
|
||||||
require.Nil(t, err, "could not parse GET request")
|
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
|
request, err = Parse(`GET ?username=test&password=test HTTP/1.1
|
||||||
Host: {{Hostname}}:123`, "https://example.com:8080/test/", false)
|
Host: {{Hostname}}:123`, "https://example.com:8080/test/", false)
|
||||||
require.Nil(t, err, "could not parse GET request")
|
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
|
request, err = Parse(`GET /?username=test&password=test HTTP/1.1
|
||||||
Host: {{Hostname}}:123`, "https://example.com:8080/test/", false)
|
Host: {{Hostname}}:123`, "https://example.com:8080/test/", false)
|
||||||
require.Nil(t, err, "could not parse GET request")
|
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 {
|
if req.rawRequest != nil {
|
||||||
req.rawRequest.Headers[k] = v
|
req.rawRequest.Headers[k] = v
|
||||||
} else {
|
} 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