GHSA-qhh4-458h-xwh2 @cyclonedx/cdxgen: Docker registry auth substring match forwards credentials to a different registry

Not scored Published

An attacker can steal Docker registry credentials by exploiting substring matching logic that forwards private registry credentials to unrelated public registries.

Exploited in the wild
Not known
Login needed
Not needed
Attackable
Over the internet
Victim action needed
Not needed
Fix
Available

What is GHSA-qhh4-458h-xwh2?

GHSA-qhh4-458h-xwh2 is a vulnerability in @cyclonedx/cdxgen, published on 8 May 2026. An attacker can exploit it over the internet without logging in, with no action from the victim.

Official description

Docker registry auth substring match forwards credentials to a different registry

Repository

cdxgen/cdxgen

Affected product/package

  • Ecosystem: npm
  • Package: @cyclonedx/cdxgen
  • Reviewed tree version: 12.3.3
  • Reviewed commit: b1e179869fd7c6032c3d483c3f7bd4d7154ec22b
  • Affected file: lib/managers/docker.js
  • Affected from: v9.9.5

The Single Executable Applications (SEA) binaries and container images are also affected.

Weakness

CWE-522 / CWE-346.

Summary

When cdxgen scans or pulls container images through the Docker daemon API, it builds an X-Registry-Auth header from Docker credentials in DOCKER_CONFIG/config.json. The credential selection logic matches configured registry keys with substring checks:

if (forRegistry && !serverAddress.includes(forRegistry)) {
  continue;
}

This is not an origin-safe registry comparison. For example, credentials configured for private-registry.example.com are selected for a requested image under registry.example.com, because:

"private-registry.example.com".includes("registry.example.com") === true

The selected credentials are then serialized into X-Registry-Auth for the Docker API pull request targeting the requested registry.

Reproduction

Use the attached/local proof:

node submissions/github-gsa/cdxgen-docker-registry-auth-substring-forwarding/evidence/cdxgen_docker_registry_auth_substring_probe.mjs

The proof is fully local. It creates a temporary Docker config containing credentials for private-registry.example.com, starts a localhost mock Docker API endpoint, sets DOCKER_HOST to that endpoint, then calls cdxgen's exported Docker request path for a pull from registry.example.com.

Observed vulnerable output:

{
  "decision": "GO",
  "dockerConfigAuthHost": "private-registry.example.com",
  "requestedRegistry": "registry.example.com",
  "substringMatch": true,
  "dockerApiUrl": "/images/create?fromImage=registry.example.com/team/app:latest",
  "headerPresent": true,
  "decodedHeader": {
    "username": "trusted-user",
    "password": "trusted-pass",
    "serveraddress": "private-registry.example.com"
  }
}

Impact

If an operator has Docker credentials for a private registry and uses cdxgen to scan an image from a different registry whose hostname is a substring of that private registry hostname, cdxgen can attach the private registry credentials to the Docker pull request for the different registry.

In a realistic attack, an attacker who controls or can observe the requested registry can induce a victim to scan an image from that registry. The Docker daemon API receives an X-Registry-Auth payload containing credentials for the victim's private registry but associated with the attacker-requested pull. This is a credential forwarding/misbinding issue in cdxgen's container image handling.

References

Functions normalizeRegistryHost and registriesMatch added to normalize and perform strict host matching.

Fix PR: https://github.com/cdxgen/cdxgen/pull/3964

Researcher: Francesco SabiuResearcher: Francesco Sabiu

Which versions are affected by GHSA-qhh4-458h-xwh2?

2 open source packages ship an affected version, including @cyclonedx/cdxgen.

PackageAffectedFixed in
@cyclonedx/cdxgen npmFrom 9.9.512.3.3
@cyclonedx/cdxgen npmFrom 9.9.512.3.3

How do I fix GHSA-qhh4-458h-xwh2?

Upgrade @cyclonedx/cdxgen to 12.3.3 or later.

Is GHSA-qhh4-458h-xwh2 being exploited?

There is no known exploitation of GHSA-qhh4-458h-xwh2 in the wild and no public exploit code.

Sources

Is GHSA-qhh4-458h-xwh2 in your software?

Upload an SBOM and sbomify checks it against every vulnerability here, every day.

Check your SBOMs for free