diff --git a/internal/api/errorcodes.go b/internal/api/errorcodes.go index 9038dc25d..ce36bb65c 100644 --- a/internal/api/errorcodes.go +++ b/internal/api/errorcodes.go @@ -76,7 +76,6 @@ const ( ErrorCodeHookTimeout ErrorCode = "hook_timeout" ErrorCodeHookTimeoutAfterRetry ErrorCode = "hook_timeout_after_retry" ErrorCodeHookPayloadOverSizeLimit ErrorCode = "hook_payload_over_size_limit" - ErrorCodeHookPayloadUnknownSize ErrorCode = "hook_payload_unknown_size" ErrorCodeRequestTimeout ErrorCode = "request_timeout" ErrorCodeMFAPhoneEnrollDisabled ErrorCode = "mfa_phone_enroll_not_enabled" ErrorCodeMFAPhoneVerifyDisabled ErrorCode = "mfa_phone_verify_not_enabled" diff --git a/internal/api/hooks.go b/internal/api/hooks.go index 197a62f15..7b89dc561 100644 --- a/internal/api/hooks.go +++ b/internal/api/hooks.go @@ -152,18 +152,17 @@ func (a *API) runHTTPHook(r *http.Request, hookConfig conf.ExtensibilityPointCon if rsp.Body == nil { return nil, nil } - contentLength := rsp.ContentLength - if contentLength == -1 { - return nil, unprocessableEntityError(ErrorCodeHookPayloadUnknownSize, "Payload size not known") - } - if contentLength >= PayloadLimit { - return nil, unprocessableEntityError(ErrorCodeHookPayloadOverSizeLimit, fmt.Sprintf("Payload size is: %d bytes exceeded size limit of %d bytes", contentLength, PayloadLimit)) - } - limitedReader := io.LimitedReader{R: rsp.Body, N: contentLength} + limitedReader := io.LimitedReader{R: rsp.Body, N: PayloadLimit} body, err := io.ReadAll(&limitedReader) if err != nil { return nil, err } + if limitedReader.N <= 0 { + // check if the response body still has excess bytes to be read + if n, _ := rsp.Body.Read(make([]byte, 1)); n > 0 { + return nil, unprocessableEntityError(ErrorCodeHookPayloadOverSizeLimit, fmt.Sprintf("Payload size exceeded size limit of %d bytes", PayloadLimit)) + } + } return body, nil case http.StatusTooManyRequests, http.StatusServiceUnavailable: retryAfterHeader := rsp.Header.Get("retry-after")