From 19a95d8c5528785a224cdd5641fbf7fa1eb5ee0c Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Sat, 7 Oct 2023 11:28:16 +0200 Subject: [PATCH] httpfs: limit body size Signed-off-by: Nicola Murino --- internal/dataprovider/node.go | 8 ++++++-- internal/vfs/httpfs.go | 36 +++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/internal/dataprovider/node.go b/internal/dataprovider/node.go index 2e20af14..32591219 100644 --- a/internal/dataprovider/node.go +++ b/internal/dataprovider/node.go @@ -232,9 +232,13 @@ func (n *Node) SendGetRequest(username, role, relativeURL string, responseHolder if resp.StatusCode < http.StatusOK || resp.StatusCode > http.StatusNoContent { return fmt.Errorf("unexpected status code: %d", resp.StatusCode) } - err = json.NewDecoder(resp.Body).Decode(responseHolder) + respBody, err := io.ReadAll(io.LimitReader(resp.Body, 10485760)) if err != nil { - return fmt.Errorf("unable to decode response as json") + return fmt.Errorf("unable to read response body: %w", err) + } + err = json.Unmarshal(respBody, responseHolder) + if err != nil { + return errors.New("unable to decode response as json") } return nil } diff --git a/internal/vfs/httpfs.go b/internal/vfs/httpfs.go index 2961ab32..a2200ec3 100644 --- a/internal/vfs/httpfs.go +++ b/internal/vfs/httpfs.go @@ -44,7 +44,8 @@ import ( const ( // httpFsName is the name for the HTTP Fs implementation - httpFsName = "httpfs" + httpFsName = "httpfs" + maxHTTPFsResponseSize = 1048576 ) var ( @@ -283,8 +284,12 @@ func (fs *HTTPFs) Stat(name string) (os.FileInfo, error) { } defer resp.Body.Close() + respBody, err := io.ReadAll(io.LimitReader(resp.Body, maxHTTPFsResponseSize)) + if err != nil { + return nil, err + } var response statResponse - err = json.NewDecoder(resp.Body).Decode(&response) + err = json.Unmarshal(respBody, &response) if err != nil { return nil, err } @@ -479,8 +484,12 @@ func (fs *HTTPFs) ReadDir(dirname string) ([]os.FileInfo, error) { } defer resp.Body.Close() + respBody, err := io.ReadAll(io.LimitReader(resp.Body, maxHTTPFsResponseSize*10)) + if err != nil { + return nil, err + } var response []statResponse - err = json.NewDecoder(resp.Body).Decode(&response) + err = json.Unmarshal(respBody, &response) if err != nil { return nil, err } @@ -550,8 +559,13 @@ func (fs *HTTPFs) GetDirSize(dirname string) (int, int64, error) { } defer resp.Body.Close() + respBody, err := io.ReadAll(io.LimitReader(resp.Body, maxHTTPFsResponseSize)) + if err != nil { + return 0, 0, err + } + var response dirSizeResponse - err = json.NewDecoder(resp.Body).Decode(&response) + err = json.Unmarshal(respBody, &response) if err != nil { return 0, 0, err } @@ -621,8 +635,13 @@ func (fs *HTTPFs) GetMimeType(name string) (string, error) { } defer resp.Body.Close() + respBody, err := io.ReadAll(io.LimitReader(resp.Body, maxHTTPFsResponseSize)) + if err != nil { + return "", err + } + var response mimeTypeResponse - err = json.NewDecoder(resp.Body).Decode(&response) + err = json.Unmarshal(respBody, &response) if err != nil { return "", err } @@ -646,8 +665,13 @@ func (fs *HTTPFs) GetAvailableDiskSize(dirName string) (*sftp.StatVFS, error) { } defer resp.Body.Close() + respBody, err := io.ReadAll(io.LimitReader(resp.Body, maxHTTPFsResponseSize)) + if err != nil { + return nil, err + } + var response statVFSResponse - err = json.NewDecoder(resp.Body).Decode(&response) + err = json.Unmarshal(respBody, &response) if err != nil { return nil, err }