diff --git a/pkg/credentialprovider/azure/azure_acr_helper.go b/pkg/credentialprovider/azure/azure_acr_helper.go index ea740d3fe17..1c6e0e94e6c 100644 --- a/pkg/credentialprovider/azure/azure_acr_helper.go +++ b/pkg/credentialprovider/azure/azure_acr_helper.go @@ -47,7 +47,9 @@ package azure import ( "bytes" "encoding/json" + "errors" "fmt" + "io" "io/ioutil" "net/http" "net/url" @@ -178,10 +180,15 @@ func performTokenExchange( } var content []byte - if content, err = ioutil.ReadAll(exchange.Body); err != nil { + limitedReader := &io.LimitedReader{R: exchange.Body, N: maxReadLength} + if content, err = ioutil.ReadAll(limitedReader); err != nil { return "", fmt.Errorf("Www-Authenticate: error reading response from %s", authEndpoint) } + if limitedReader.N <= 0 { + return "", errors.New("the read limit is reached") + } + var authResp acrAuthResponse if err = json.Unmarshal(content, &authResp); err != nil { return "", fmt.Errorf("Www-Authenticate: unable to read response %s", content) diff --git a/pkg/credentialprovider/azure/azure_credentials.go b/pkg/credentialprovider/azure/azure_credentials.go index 199addf78aa..555fed24c4d 100644 --- a/pkg/credentialprovider/azure/azure_credentials.go +++ b/pkg/credentialprovider/azure/azure_credentials.go @@ -18,6 +18,7 @@ package azure import ( "context" + "errors" "io" "io/ioutil" "os" @@ -38,7 +39,10 @@ import ( var flagConfigFile = pflag.String("azure-container-registry-config", "", "Path to the file containing Azure container registry configuration information.") -const dummyRegistryEmail = "name@contoso.com" +const ( + dummyRegistryEmail = "name@contoso.com" + maxReadLength = 10 * 1 << 20 // 10MB +) var containerRegistryUrls = []string{"*.azurecr.io", "*.azurecr.cn", "*.azurecr.de", "*.azurecr.us"} @@ -117,10 +121,14 @@ func parseConfig(configReader io.Reader) (*auth.AzureAuthConfig, error) { return &config, nil } - configContents, err := ioutil.ReadAll(configReader) + limitedReader := &io.LimitedReader{R: configReader, N: maxReadLength} + configContents, err := ioutil.ReadAll(limitedReader) if err != nil { return nil, err } + if limitedReader.N <= 0 { + return nil, errors.New("the read limit is reached") + } err = yaml.Unmarshal(configContents, &config) if err != nil { return nil, err diff --git a/pkg/credentialprovider/config.go b/pkg/credentialprovider/config.go index a43e8c2b15d..a877658667b 100644 --- a/pkg/credentialprovider/config.go +++ b/pkg/credentialprovider/config.go @@ -19,7 +19,9 @@ package credentialprovider import ( "encoding/base64" "encoding/json" + "errors" "fmt" + "io" "io/ioutil" "net/http" "os" @@ -30,6 +32,10 @@ import ( "k8s.io/klog" ) +const ( + maxReadLength = 10 * 1 << 20 // 10MB +) + // DockerConfigJson represents ~/.docker/config.json file info // see https://github.com/docker/docker/pull/12009 type DockerConfigJson struct { @@ -195,11 +201,16 @@ func ReadUrl(url string, client *http.Client, header *http.Header) (body []byte, } } - contents, err := ioutil.ReadAll(resp.Body) + limitedReader := &io.LimitedReader{R: resp.Body, N: maxReadLength} + contents, err := ioutil.ReadAll(limitedReader) if err != nil { return nil, err } + if limitedReader.N <= 0 { + return nil, errors.New("the read limit is reached") + } + return contents, nil }