mirror of
https://github.com/minio/minio.git
synced 2025-04-17 01:10:29 -04:00
fix: reject invalid r.Host headers (#14846)
r.Host headers can come in unparsed that may contain invalid hostnames, reject such requests as invalid. This is a continuation fix from #14844
This commit is contained in:
parent
cff1be0ae8
commit
2719f1efaa
@ -18,6 +18,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
@ -295,6 +296,15 @@ const (
|
|||||||
dotComponent = "."
|
dotComponent = "."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func hasBadHost(host string) error {
|
||||||
|
if globalIsCICD && strings.TrimSpace(host) == "" {
|
||||||
|
// under CI/CD test setups ignore empty hosts as invalid hosts
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
_, err := xnet.ParseHost(host)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the incoming path has bad path components,
|
// Check if the incoming path has bad path components,
|
||||||
// such as ".." and "."
|
// such as ".." and "."
|
||||||
func hasBadPathComponent(path string) bool {
|
func hasBadPathComponent(path string) bool {
|
||||||
@ -313,7 +323,11 @@ func hasBadPathComponent(path string) bool {
|
|||||||
// Check if client is sending a malicious request.
|
// Check if client is sending a malicious request.
|
||||||
func hasMultipleAuth(r *http.Request) bool {
|
func hasMultipleAuth(r *http.Request) bool {
|
||||||
authTypeCount := 0
|
authTypeCount := 0
|
||||||
for _, hasValidAuth := range []func(*http.Request) bool{isRequestSignatureV2, isRequestPresignedSignatureV2, isRequestSignatureV4, isRequestPresignedSignatureV4, isRequestJWT, isRequestPostPolicySignatureV4} {
|
for _, hasValidAuth := range []func(*http.Request) bool{
|
||||||
|
isRequestSignatureV2, isRequestPresignedSignatureV2,
|
||||||
|
isRequestSignatureV4, isRequestPresignedSignatureV4,
|
||||||
|
isRequestJWT, isRequestPostPolicySignatureV4,
|
||||||
|
} {
|
||||||
if hasValidAuth(r) {
|
if hasValidAuth(r) {
|
||||||
authTypeCount++
|
authTypeCount++
|
||||||
}
|
}
|
||||||
@ -325,6 +339,14 @@ func hasMultipleAuth(r *http.Request) bool {
|
|||||||
// any malicious requests.
|
// any malicious requests.
|
||||||
func setRequestValidityHandler(h http.Handler) http.Handler {
|
func setRequestValidityHandler(h http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if err := hasBadHost(r.Host); err != nil {
|
||||||
|
invalidReq := errorCodes.ToAPIErr(ErrInvalidRequest)
|
||||||
|
invalidReq.Description = fmt.Sprintf("%s (%s)", invalidReq.Description, err)
|
||||||
|
writeErrorResponse(r.Context(), w, invalidReq, r.URL)
|
||||||
|
atomic.AddUint64(&globalHTTPStats.rejectedRequestsInvalid, 1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Check for bad components in URL path.
|
// Check for bad components in URL path.
|
||||||
if hasBadPathComponent(r.URL.Path) {
|
if hasBadPathComponent(r.URL.Path) {
|
||||||
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL)
|
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL)
|
||||||
@ -342,7 +364,9 @@ func setRequestValidityHandler(h http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if hasMultipleAuth(r) {
|
if hasMultipleAuth(r) {
|
||||||
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL)
|
invalidReq := errorCodes.ToAPIErr(ErrInvalidRequest)
|
||||||
|
invalidReq.Description = fmt.Sprintf("%s (request has multiple authentication types, please use one)", invalidReq.Description)
|
||||||
|
writeErrorResponse(r.Context(), w, invalidReq, r.URL)
|
||||||
atomic.AddUint64(&globalHTTPStats.rejectedRequestsInvalid, 1)
|
atomic.AddUint64(&globalHTTPStats.rejectedRequestsInvalid, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user