Docker CLI leaks private registry credentials to registry-1.docker.io
Description
Docker CLI is the command line interface for the docker container runtime. A bug was found in the Docker CLI where running docker login my-private-registry.example.com with a misconfigured configuration file (typically ~/.docker/config.json) listing a credsStore or credHelpers that could not be executed would result in any provided credentials being sent to registry-1.docker.io rather than the intended private registry. This bug has been fixed in Docker CLI 20.10.9. Users should update to this version as soon as possible. For users unable to update ensure that any configured credsStore or credHelpers entries in the configuration file reference an installed credential helper that is executable and on the PATH.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A bug in Docker CLI prior to 20.10.9 causes credentials intended for a private registry to be sent to Docker Hub when credential helpers are misconfigured.
Vulnerability
The Docker CLI prior to version 20.10.9 contains a bug where running docker login my-private-registry.example.com with a misconfigured ~/.docker/config.json file that specifies a credsStore or credHelpers entry pointing to an unexecutable or missing credential helper results in the provided credentials being sent to registry-1.docker.io instead of the intended private registry [1].
Exploitation
An attacker does not require direct network access; the vulnerability is triggered when a user executes docker login for a private registry while their configuration file contains a credential helper that cannot be executed. The CLI fails to properly handle the error and defaults to sending credentials to Docker Hub. No user interaction beyond the normal login command is needed, and the user receives no warning of the misdirection [1].
Impact
Successful exploitation leads to disclosure of the user's private registry credentials to Docker Hub, compromising their confidentiality. An attacker who can observe the credentials at Docker Hub could then access the private registry with the victim's privileges, potentially leading to further compromise [1].
Mitigation
The vulnerability is fixed in Docker CLI version 20.10.9, released on October 4, 2021. Users should update to this version or later. For those unable to update, ensure that any configured credsStore or credHelpers entries in the configuration file reference an installed credential helper that is executable and available on the PATH [1][2].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/docker/cliGo | < 20.10.9 | 20.10.9 |
Affected products
77- osv-coords76 versionspkg:apk/chainguard/divepkg:apk/wolfi/divepkg:bitnami/docker-clipkg:golang/github.com/docker/clipkg:rpm/opensuse/containerd&distro=openSUSE%20Leap%2015.2pkg:rpm/opensuse/containerd&distro=openSUSE%20Leap%2015.3pkg:rpm/opensuse/docker&distro=openSUSE%20Leap%2015.2pkg:rpm/opensuse/docker&distro=openSUSE%20Leap%2015.3pkg:rpm/opensuse/docker&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/docker-kubic&distro=openSUSE%20Leap%2015.3pkg:rpm/opensuse/docker-stable&distro=openSUSE%20Leap%2015.6pkg:rpm/opensuse/docker-stable&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/runc&distro=openSUSE%20Leap%2015.2pkg:rpm/opensuse/runc&distro=openSUSE%20Leap%2015.3pkg:rpm/suse/containerd&distro=SUSE%20Enterprise%20Storage%206pkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-ESPOSpkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-LTSSpkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-ESPOSpkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-LTSSpkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20Micro%205.0pkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20Micro%205.1pkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2012pkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2015%20SP2pkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2015%20SP3pkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-BCLpkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-LTSSpkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20Server%2015-LTSSpkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015pkg:rpm/suse/containerd&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015%20SP1pkg:rpm/suse/docker&distro=SUSE%20Enterprise%20Storage%206pkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-ESPOSpkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-LTSSpkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-ESPOSpkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-LTSSpkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20Micro%205.0pkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20Micro%205.1pkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2012pkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2015%20SP2pkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2015%20SP3pkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-BCLpkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-LTSSpkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20Server%2015-LTSSpkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015pkg:rpm/suse/docker&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015%20SP1pkg:rpm/suse/docker-stable&distro=SUSE%20Enterprise%20Storage%207.1pkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP3-LTSSpkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP4-ESPOSpkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP4-LTSSpkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP5-ESPOSpkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP5-LTSSpkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2015%20SP6pkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2015%20SP7pkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP5-LTSSpkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP3-LTSSpkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP4-LTSSpkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP5-LTSSpkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015%20SP3pkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015%20SP4pkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015%20SP5pkg:rpm/suse/docker-stable&distro=SUSE%20Linux%20Enterprise%20Server%20LTSS%20Extended%20Security%2012%20SP5pkg:rpm/suse/runc&distro=SUSE%20Enterprise%20Storage%206pkg:rpm/suse/runc&distro=SUSE%20Enterprise%20Storage%207pkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-ESPOSpkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-LTSSpkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-ESPOSpkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-LTSSpkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20Micro%205.0pkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20Micro%205.1pkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2012pkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2015%20SP2pkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Containers%2015%20SP3pkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-BCLpkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-LTSSpkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20Server%2015-LTSSpkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015pkg:rpm/suse/runc&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015%20SP1
< 0.12.0-r8+ 75 more
- (no CPE)range: < 0.12.0-r8
- (no CPE)range: < 0.12.0-r8
- (no CPE)range: < 20.10.9
- (no CPE)range: < 20.10.9
- (no CPE)range: < 1.4.11-lp152.2.12.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 20.10.9_ce-lp152.2.18.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-1.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-15.1
- (no CPE)range: < 1.0.2-lp152.2.9.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-16.45.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 1.4.11-56.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-98.72.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 20.10.9_ce-156.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-1.20.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-150000.1.25.1
- (no CPE)range: < 24.0.9_ce-1.20.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-16.14.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- (no CPE)range: < 1.0.2-23.1
- docker/cliv5Range: < 20.10.9
Patches
1893e52cf4ba4Merge pull request #2 from moby/cli-ghsa-99pg-grm5-qq3v-default-authconfig-20.10
3 files changed · +27 −17
cli/command/registry.go+7 −8 modified@@ -63,17 +63,14 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf indexServer := registry.GetAuthConfigKey(index) isDefaultRegistry := indexServer == ElectAuthServer(context.Background(), cli) authConfig, err := GetDefaultAuthConfig(cli, true, indexServer, isDefaultRegistry) - if authConfig == nil { - authConfig = &types.AuthConfig{} - } if err != nil { fmt.Fprintf(cli.Err(), "Unable to retrieve stored credentials for %s, error: %s.\n", indexServer, err) } - err = ConfigureAuth(cli, "", "", authConfig, isDefaultRegistry) + err = ConfigureAuth(cli, "", "", &authConfig, isDefaultRegistry) if err != nil { return "", err } - return EncodeAuthToBase64(*authConfig) + return EncodeAuthToBase64(authConfig) } } @@ -92,7 +89,7 @@ func ResolveAuthConfig(ctx context.Context, cli Cli, index *registrytypes.IndexI // GetDefaultAuthConfig gets the default auth config given a serverAddress // If credentials for given serverAddress exists in the credential store, the configuration will be populated with values in it -func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (*types.AuthConfig, error) { +func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, isDefaultRegistry bool) (types.AuthConfig, error) { if !isDefaultRegistry { serverAddress = registry.ConvertToHostname(serverAddress) } @@ -101,13 +98,15 @@ func GetDefaultAuthConfig(cli Cli, checkCredStore bool, serverAddress string, is if checkCredStore { authconfig, err = cli.ConfigFile().GetAuthConfig(serverAddress) if err != nil { - return nil, err + return types.AuthConfig{ + ServerAddress: serverAddress, + }, err } } authconfig.ServerAddress = serverAddress authconfig.IdentityToken = "" res := types.AuthConfig(authconfig) - return &res, nil + return res, nil } // ConfigureAuth handles prompting of user's username and password if needed
cli/command/registry/login.go+5 −8 modified@@ -114,22 +114,19 @@ func runLogin(dockerCli command.Cli, opts loginOptions) error { //nolint: gocycl var response registrytypes.AuthenticateOKBody isDefaultRegistry := serverAddress == authServer authConfig, err := command.GetDefaultAuthConfig(dockerCli, opts.user == "" && opts.password == "", serverAddress, isDefaultRegistry) - if authConfig == nil { - authConfig = &types.AuthConfig{} - } if err == nil && authConfig.Username != "" && authConfig.Password != "" { - response, err = loginWithCredStoreCreds(ctx, dockerCli, authConfig) + response, err = loginWithCredStoreCreds(ctx, dockerCli, &authConfig) } if err != nil || authConfig.Username == "" || authConfig.Password == "" { - err = command.ConfigureAuth(dockerCli, opts.user, opts.password, authConfig, isDefaultRegistry) + err = command.ConfigureAuth(dockerCli, opts.user, opts.password, &authConfig, isDefaultRegistry) if err != nil { return err } - response, err = clnt.RegistryLogin(ctx, *authConfig) + response, err = clnt.RegistryLogin(ctx, authConfig) if err != nil && client.IsErrConnectionFailed(err) { // If the server isn't responding (yet) attempt to login purely client side - response, err = loginClientSide(ctx, *authConfig) + response, err = loginClientSide(ctx, authConfig) } // If we (still) have an error, give up if err != nil { @@ -152,7 +149,7 @@ func runLogin(dockerCli command.Cli, opts loginOptions) error { //nolint: gocycl } } - if err := creds.Store(configtypes.AuthConfig(*authConfig)); err != nil { + if err := creds.Store(configtypes.AuthConfig(authConfig)); err != nil { return errors.Errorf("Error saving credentials: %v", err) }
cli/command/registry_test.go+15 −1 modified@@ -145,7 +145,21 @@ func TestGetDefaultAuthConfig(t *testing.T) { assert.Check(t, is.Equal(tc.expectedErr, err.Error())) } else { assert.NilError(t, err) - assert.Check(t, is.DeepEqual(tc.expectedAuthConfig, *authconfig)) + assert.Check(t, is.DeepEqual(tc.expectedAuthConfig, authconfig)) } } } + +func TestGetDefaultAuthConfig_HelperError(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{}) + errBuf := new(bytes.Buffer) + cli.SetErr(errBuf) + cli.ConfigFile().CredentialsStore = "fake-does-not-exist" + serverAddress := "test-server-address" + expectedAuthConfig := types.AuthConfig{ + ServerAddress: serverAddress, + } + authconfig, err := GetDefaultAuthConfig(cli, true, serverAddress, serverAddress == "https://index.docker.io/v1/") + assert.Check(t, is.DeepEqual(expectedAuthConfig, authconfig)) + assert.Check(t, is.ErrorContains(err, "docker-credential-fake-does-not-exist")) +}
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- github.com/advisories/GHSA-99pg-grm5-qq3vghsaADVISORY
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/B5Q6G6I4W5COQE25QMC7FJY3I3PAYFBB/mitrevendor-advisoryx_refsource_FEDORA
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/ZNFADTCHHYWVM6W4NJ6CB4FNFM2VMBIB/mitrevendor-advisoryx_refsource_FEDORA
- nvd.nist.gov/vuln/detail/CVE-2021-41092ghsaADVISORY
- cert-portal.siemens.com/productcert/pdf/ssa-222547.pdfghsax_refsource_CONFIRMWEB
- github.com/docker/cli/commit/893e52cf4ba4b048d72e99748e0f86b2767c6c6bghsax_refsource_MISCWEB
- github.com/docker/cli/security/advisories/GHSA-99pg-grm5-qq3vghsax_refsource_CONFIRMWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/B5Q6G6I4W5COQE25QMC7FJY3I3PAYFBBghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZNFADTCHHYWVM6W4NJ6CB4FNFM2VMBIBghsaWEB
News mentions
0No linked articles in our index yet.