VYPR
Moderate severityNVD Advisory· Published Dec 7, 2020· Updated Sep 16, 2024

Docker config secrets leaked when file is malformed and loglevel >= 4

CVE-2020-8564

Description

In Kubernetes clusters using a logging level of at least 4, processing a malformed docker config file will result in the contents of the docker config file being leaked, which can include pull secrets or other registry credentials. This affects < v1.19.3, < v1.18.10, < v1.17.13.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/kubernetes/kubernetesGo
>= 1.19.0, < 1.19.31.19.3
github.com/kubernetes/kubernetesGo
>= 1.18.0, < 1.18.101.18.10
github.com/kubernetes/kubernetesGo
< 1.17.131.17.13
k8s.io/kubernetesGo
< 1.20.0-alpha.11.20.0-alpha.1

Affected products

1

Patches

1
11793434dac9

Merge pull request #94712 from droslean/cred-leak

https://github.com/kubernetes/kubernetesKubernetes Prow RobotSep 14, 2020via ghsa
2 files changed · +102 7
  • pkg/credentialprovider/config.go+9 7 modified
    @@ -117,10 +117,14 @@ func ReadDockercfgFile(searchPaths []string) (cfg DockerConfig, err error) {
     			continue
     		}
     		cfg, err := readDockerConfigFileFromBytes(contents)
    -		if err == nil {
    -			klog.V(4).Infof("found .dockercfg at %s", absDockerConfigFileLocation)
    -			return cfg, nil
    +		if err != nil {
    +			klog.V(4).Infof("couldn't get the config from %q contents: %v", absDockerConfigFileLocation, err)
    +			continue
     		}
    +
    +		klog.V(4).Infof("found .dockercfg at %s", absDockerConfigFileLocation)
    +		return cfg, nil
    +
     	}
     	return nil, fmt.Errorf("couldn't find valid .dockercfg after checking in %v", searchPaths)
     }
    @@ -230,17 +234,15 @@ func ReadDockerConfigFileFromURL(url string, client *http.Client, header *http.H
     
     func readDockerConfigFileFromBytes(contents []byte) (cfg DockerConfig, err error) {
     	if err = json.Unmarshal(contents, &cfg); err != nil {
    -		klog.Errorf("while trying to parse blob %q: %v", contents, err)
    -		return nil, err
    +		return nil, errors.New("error occurred while trying to unmarshal json")
     	}
     	return
     }
     
     func readDockerConfigJSONFileFromBytes(contents []byte) (cfg DockerConfig, err error) {
     	var cfgJSON DockerConfigJSON
     	if err = json.Unmarshal(contents, &cfgJSON); err != nil {
    -		klog.Errorf("while trying to parse blob %q: %v", contents, err)
    -		return nil, err
    +		return nil, errors.New("error occurred while trying to unmarshal json")
     	}
     	cfg = cfgJSON.Auths
     	return
    
  • pkg/credentialprovider/config_test.go+93 0 modified
    @@ -309,3 +309,96 @@ func TestDockerConfigEntryJSONCompatibleEncode(t *testing.T) {
     		}
     	}
     }
    +
    +func TestReadDockerConfigFileFromBytes(t *testing.T) {
    +	testCases := []struct {
    +		id               string
    +		input            []byte
    +		expectedCfg      DockerConfig
    +		errorExpected    bool
    +		expectedErrorMsg string
    +	}{
    +		{
    +			id:    "valid input, no error expected",
    +			input: []byte(`{"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}}`),
    +			expectedCfg: DockerConfig(map[string]DockerConfigEntry{
    +				"http://foo.example.com": {
    +					Username: "foo",
    +					Password: "bar",
    +					Email:    "foo@example.com",
    +				},
    +			}),
    +		},
    +		{
    +			id:               "invalid input, error expected",
    +			input:            []byte(`{"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"`),
    +			errorExpected:    true,
    +			expectedErrorMsg: "error occurred while trying to unmarshal json",
    +		},
    +	}
    +
    +	for _, tc := range testCases {
    +		cfg, err := readDockerConfigFileFromBytes(tc.input)
    +		if err != nil && !tc.errorExpected {
    +			t.Fatalf("Error was not expected: %v", err)
    +		}
    +		if err != nil && tc.errorExpected {
    +			if !reflect.DeepEqual(err.Error(), tc.expectedErrorMsg) {
    +				t.Fatalf("Expected error message: `%s` got `%s`", tc.expectedErrorMsg, err.Error())
    +			}
    +		} else {
    +			if !reflect.DeepEqual(cfg, tc.expectedCfg) {
    +				t.Fatalf("expected: %v got %v", tc.expectedCfg, cfg)
    +			}
    +		}
    +	}
    +}
    +
    +func TestReadDockerConfigJSONFileFromBytes(t *testing.T) {
    +	testCases := []struct {
    +		id               string
    +		input            []byte
    +		expectedCfg      DockerConfig
    +		errorExpected    bool
    +		expectedErrorMsg string
    +	}{
    +		{
    +			id:    "valid input, no error expected",
    +			input: []byte(`{"auths": {"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}, "http://bar.example.com":{"username": "bar", "password": "baz", "email": "bar@example.com"}}}`),
    +			expectedCfg: DockerConfig(map[string]DockerConfigEntry{
    +				"http://foo.example.com": {
    +					Username: "foo",
    +					Password: "bar",
    +					Email:    "foo@example.com",
    +				},
    +				"http://bar.example.com": {
    +					Username: "bar",
    +					Password: "baz",
    +					Email:    "bar@example.com",
    +				},
    +			}),
    +		},
    +		{
    +			id:               "invalid input, error expected",
    +			input:            []byte(`{"auths": {"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}, "http://bar.example.com":{"username": "bar", "password": "baz", "email": "bar@example.com"`),
    +			errorExpected:    true,
    +			expectedErrorMsg: "error occurred while trying to unmarshal json",
    +		},
    +	}
    +
    +	for _, tc := range testCases {
    +		cfg, err := readDockerConfigJSONFileFromBytes(tc.input)
    +		if err != nil && !tc.errorExpected {
    +			t.Fatalf("Error was not expected: %v", err)
    +		}
    +		if err != nil && tc.errorExpected {
    +			if !reflect.DeepEqual(err.Error(), tc.expectedErrorMsg) {
    +				t.Fatalf("Expected error message: `%s` got `%s`", tc.expectedErrorMsg, err.Error())
    +			}
    +		} else {
    +			if !reflect.DeepEqual(cfg, tc.expectedCfg) {
    +				t.Fatalf("expected: %v got %v", tc.expectedCfg, cfg)
    +			}
    +		}
    +	}
    +}
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.