From 45e4d380b4164ce983353fa8c0bb19d15cd45bdd Mon Sep 17 00:00:00 2001 From: Jacob Weinstock Date: Fri, 8 Sep 2023 11:43:37 -0600 Subject: [PATCH] Add max allowed response content size: This guards against dos attacks that might send very large responses. Signed-off-by: Jacob Weinstock --- providers/rpc/http_test.go | 13 +++++++++++++ providers/rpc/rpc.go | 10 +++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/providers/rpc/http_test.go b/providers/rpc/http_test.go index e386ff60..3d837b08 100644 --- a/providers/rpc/http_test.go +++ b/providers/rpc/http_test.go @@ -151,3 +151,16 @@ func TestCreateRequest(t *testing.T) { }) } } + +func TestContentSize(t *testing.T) { + prov := New("http://127.0.0.1/rpc", "127.0.2.1", Secrets{SHA256: {"superSecret1"}}) + _ = prov.Open(context.Background()) + reqPayload := RequestPayload{ID: 1, Host: "127.0.0.1", Method: PowerGetMethod} + req, err := prov.createRequest(context.Background(), reqPayload) + if err != nil { + t.Fatal(err) + } + if req.ContentLength > maxContentLenAllowed { + t.Fatalf("unexpected content length: got: %d, want: %v", req.ContentLength, maxContentLenAllowed) + } +} diff --git a/providers/rpc/rpc.go b/providers/rpc/rpc.go index e75d0f7d..aa7f679b 100644 --- a/providers/rpc/rpc.go +++ b/providers/rpc/rpc.go @@ -25,9 +25,10 @@ const ( ProviderProtocol = "http" // defaults - timestampHeader = "X-BMCLIB-Timestamp" - signatureHeader = "X-BMCLIB-Signature" - contentType = "application/json" + timestampHeader = "X-BMCLIB-Timestamp" + signatureHeader = "X-BMCLIB-Signature" + contentType = "application/json" + maxContentLenAllowed = 512 << (10 * 1) // 512KB // SHA256 is the SHA256 algorithm. SHA256 Algorithm = "sha256" @@ -326,6 +327,9 @@ func (p *Provider) process(ctx context.Context, rp RequestPayload) (ResponsePayl defer resp.Body.Close() // handle the response + if resp.ContentLength > maxContentLenAllowed { + return ResponsePayload{}, fmt.Errorf("response body is too large: %d bytes, max allowed: %d bytes", resp.ContentLength, maxContentLenAllowed) + } respPayload, err := p.handleResponse(resp, kvs) if err != nil { return ResponsePayload{}, err