mirror of
https://github.com/valyala/fasthttp.git
synced 2026-06-13 15:46:49 +03:00
Validate request URI format during header parsing to reject malformed requests (#2168)
This commit is contained in:
@@ -2866,6 +2866,13 @@ func (h *RequestHeader) parseFirstLine(buf []byte) (int, error) {
|
||||
return 0, fmt.Errorf("requestURI cannot be empty in %q", buf)
|
||||
}
|
||||
|
||||
if err := validateRequestURI(h.method, b[:n]); err != nil {
|
||||
if h.secureErrorLogMessage {
|
||||
return 0, fmt.Errorf("invalid requestURI %q", b[:n])
|
||||
}
|
||||
return 0, fmt.Errorf("invalid requestURI %q in %q: %w", b[:n], buf, err)
|
||||
}
|
||||
|
||||
// Check for extra whitespace - only one space should separate URI from HTTP version
|
||||
if n+1 < len(b) && b[n+1] == ' ' {
|
||||
if h.secureErrorLogMessage {
|
||||
@@ -2903,6 +2910,29 @@ func (h *RequestHeader) parseFirstLine(buf []byte) (int, error) {
|
||||
return len(buf) - len(bNext), nil
|
||||
}
|
||||
|
||||
func validateRequestURI(method, requestURI []byte) error {
|
||||
if stringContainsCTLByte(requestURI) {
|
||||
return ErrorInvalidURI
|
||||
}
|
||||
if len(requestURI) == 1 && requestURI[0] == '*' {
|
||||
return nil
|
||||
}
|
||||
if len(requestURI) > 0 && requestURI[0] == '/' {
|
||||
return nil
|
||||
}
|
||||
if before, _, ok := bytes.Cut(requestURI, strColonSlashSlash); ok {
|
||||
if !isValidScheme(before) {
|
||||
return ErrorInvalidURI
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// net/http treats CONNECT request-targets without a leading slash as authority-form.
|
||||
if bytes.Equal(method, strConnect) {
|
||||
return nil
|
||||
}
|
||||
return ErrorInvalidURI
|
||||
}
|
||||
|
||||
func readRawHeaders(dst, buf []byte) ([]byte, int, error) {
|
||||
n := bytes.IndexByte(buf, nChar)
|
||||
if n < 0 {
|
||||
|
||||
@@ -90,6 +90,7 @@ var (
|
||||
strBytes = []byte("bytes")
|
||||
strBasicSpace = []byte("Basic ")
|
||||
strLink = []byte("Link")
|
||||
strConnect = []byte("CONNECT")
|
||||
|
||||
strApplicationSlash = []byte("application/")
|
||||
strImageSVG = []byte("image/svg")
|
||||
|
||||
Reference in New Issue
Block a user