Prometheus exporter-toolkit Auth Bypass via Cache Poisoning (CVE-2022-46146)

  • Thread Author
Prometheus exporter-toolkit contains a serious basic‑authentication bypass that can be triggered when an attacker has access to a Prometheus-style web.yml file and the bcrypt password hashes it contains—allowing the attacker to poison an internal authentication cache and authenticate without knowing the real password. (github.com)

Cybersecurity illustration with web.yml, a firewall shield, cloud blast, and version numbers.Background / Overview​

Prometheus exposes a variety of components and exporters that often rely on a tiny shared helper library known as the exporter‑toolkit. That toolkit provides, among other things, a simple HTTP handler that implements basic authentication using Prometheus’ common web.yml file format. The file format stores usernames and bcrypt-hashed passwords; the bcrypt hashes are used to validate presented passwords without storing plaintext. The exporter‑toolkit also implements an internal cache to reduce repeated bcrypt computations and to blunt timing/side‑channel enumeration of user presence.
A logic error in that caching and validation path allowed attackers who already had access to a web.yml file (or otherwise obtained the bcrypt hashes) to craft requests that poisoned the cache and caused subsequent authentications to be accepted. The issue was disclosed and tracked as GHSA‑7rg2‑cxvp‑9p7p / CVE‑2022‑46146 and patched in the exporter‑toolkit releases listed below. (github.com)
This flaw is not an unauthenticated remote compromise in the classical sense—the attacker must first obtain the hashed password entries. However, many operational environments expose metrics or host exporter configuration artifacts in places where hashes may be accessible (image layers, config maps, backups, or misconfigured file shares), so the prerequisite is easier to meet in real-world deployments than it might appear from the abstract description.

What exactly is vulnerable​

Affected components and versions​

  • Affected package: gomod github.com/prometheus/exporter-toolkit. (github.com)
  • Affected versions: versions prior to 0.7.2 and the 0.8.0 / 0.8.1 releases (the advisory enumerates < 0.7.2 and 0.8.0, 0.8.1 as vulnerable). The maintainers released fixes in 0.7.2 / 0.7.3 and 0.8.2. (github.com)

The exploit model, in plain language​

  • Prometheus-style basic auth uses web.yml with bcrypt hashes to avoid storing plaintext passwords. Those bcrypt hashes are sensitive: possession of them reduces the attack complexity dramatically. (github.com)
  • The exporter‑toolkit cached the result of bcrypt comparisons in a composite key derived from the username, stored hash, and the password the client presented. Because of how the cache key and validation were constructed, an attacker who knows the bcrypt hash can craft requests that put cache entries into a state that causes the toolkit to treat subsequent requests as authenticated—even without the original password. The cache’s original intent was to reduce repeated expensive bcrypt operations and to mitigate timing-based user enumeration; the implementation accidentally gave an attacker a way in if the attacker already held the hash. The maintainers corrected both the key construction and the logic that allowed “fake” cache entries to validate. (github.com)

Why hashed passwords matter here​

Bcrypt hashes are designed to make offline cracking expensive, but possession of a hash is still a compromise of security assumptions: many operational mistakes make hashes available (container images with baked-in web.yml files, misconfigured config maps, backup snapshots, world-readable artifact stores, or leaked repository files). When an attacker has the hash, the exporter‑toolkit vulnerability converted that partial compromise into an authentication bypass. Multiple vulnerability trackers call this an improper authentication or incorrect authentication algorithm issue (CWE‑287 / CWE‑303). (cvedetails.com)

Technical anatomy: cache poisoning and the fix​

What went wrong — implementation details​

At a high level, the handler:
  • Reads the web.yml file to map username → bcrypt hash.
  • When a request arrives, it computes/looks up a cache key and checks the cache for a cached boolean indicating success/failure for that key.
  • If the cache entry is missing, it runs bcrypt.CompareHashAndPassword() and stores the boolean result in the cache.
Because the cache key combined raw pieces in a way that allowed collisions or ambiguous representation, and because the code sometimes stored entries for failed attempts using a “fakepassword” sentinel, an attacker could craft requests that produced a cache key that later matched a valid authentication check—even though the attacker never presented the real password. That allowed authentication to succeed purely on fabricated cache state. The maintainers reworked the cache key construction to hex‑encode and join components with an unambiguous separator, and they tightened the logic to ensure a cached "success" entry could only exist for a valid user after a real bcrypt success. The test suite was extended to cover the new checks. (github.com)

Exactly what the patch changed​

  • Cache key construction: components are now hex‑encoded and joined with ":" to prevent ambiguous concatenation that could lead to collisions.
  • Authentication logic: the cached result is only considered successful when both the user is valid and the bcrypt check passed; "fakepassword" sentinel paths no longer create success entries.
  • Tests: new unit tests were added to protect against regression for CVE‑2022‑46146. (github.com)
These are conservative, pragmatic changes that close the implementation gap without changing the authentication model.

Severity, scoring, and real‑world impact​

Different trackers compute severity using different assumptions, and that is visible here:
  • GitHub’s advisory rates the issue as High with a CVSS 3.x base around 7.2, noting Network attack vector but Privileges Required: High in their specific scoring (because possession of the hash is an explicit required privilege). (github.com)
  • Other aggregators report higher NVD-style scores in the 8.x range by modeling a scenario where the presence of the hash is treated as low privilege or more attainable, which increases confidentiality/integrity/availability impacts. (cvedetails.com)
The practical takeaway: if an attacker can obtain bcrypt hashes for users (by reading web.yml or similar artifacts), this bug allows them to authenticate as those users to any service using the vulnerable exporter‑toolkit. That can reveal sensitive metrics, telemetry, or management endpoints behind basic auth and may expose topology/operational data that aids further intrusion. The exploit is relatively straightforward once hashes are available, but the real gating factor is whether the attacker can obtain those hashes—or whether other operational mistakes make them reachable.

Detection: how to know if you’re or have been targeted​

Because exploitation requires prior access to the bcrypt hashes, detection combines two tracks: 1) evidence of information disclosure (where hashes lived), and 2) anomalous authentication/ingress patterns.
Indicators to hunt for:
  • Presence of web.yml files or bcrypt hashes in images, containers, image registries, or config maps that should not contain credentials. Search artifact repositories, Docker layers, Helm charts, and config backups for "web.yml" or the bcrypt prefix "$2y$".
  • Access logs: authentication successes from unexpected sources shortly after new exposures of configuration artifacts.
  • Unusual sequences where a single IP or client attempts many different passwords or header mutations followed by a surprising successful authentication without a known password.
  • File system audit events showing reads of web.yml or other config files by non-owner processes or unexpected service accounts.
  • Added test coverage in the exporter toolkit indicates the specific behavior corrected; if you see logs that match prior failing paths (e.g., cache hit where bcrypt was not executed), that’s a red flag. (github.com)
Operational detection checklist (quick):
  • Search your images and artifacts for web.yml or bcrypt strings.
  • Inspect Prometheus/exporter configurations for usage of exporter‑toolkit module versions < 0.7.2 or in the 0.8.0–0.8.1 band.
  • Correlate any config exposures with abnormal auth events in access logs.
  • If suspicious, assume compromise of metrics/monitoring credentials and move to containment (see remediation).

Remediation & mitigation guidance​

There are no reliable per‑instance workarounds that fully restore security without upgrading. The maintainers explicitly note no workaround and the recommended action is to upgrade to patched versions. (github.com)
Immediate actions (fast remediation)
  • Upgrade exporter‑toolkit in your builds and images to the patched releases:
  • 0.7.2 / 0.7.3 and 0.8.2 include the fix and associated tests. Confirm the exact module version used in vendor manifests, go.mod files, and built binaries. (github.com)
  • If you cannot upgrade immediately, reduce exposure by restricting access to any endpoints that rely on exporter lookups:
  • Place the metrics endpoint behind a network ACL, internal-only service mesh, or a reverse proxy that enforces stronger authentication (OAuth / mTLS). Do not rely on exporter-toolkit’s basic auth as your only line of defense while unpatched.
  • Consider disabling web.yml‑based basic auth entirely in favor of an external, well‑supported authentication front (e.g., an ingress controller with LDAP/OAuth or a reverse proxy that uses a hardened auth module). Note: this is an operational change and must be validated in test environments. (github.com)
  • If you have evidence that web.yml or bcrypt hashes were exposed, treat them as compromised:
  • Rotate affected credentials and regenerate bcrypt hashes with new strong passwords. Replace the web.yml artifacts with the new hashes and ensure old backups are removed or secured.
  • Revoke any tokens or service accounts that used the same credentials or had access to the same storage location.
Durable fixes (recommended)
  • Update your dependency hygiene: pin to the fixed exporter‑toolkit versions and rebuild all images and bundles that incorporate the library. Rebuild container images and any deliverables that might have embedded the old library. (github.com)
  • Harden storage and access controls where configuration files and hashes live: use secrets management systems, encrypted config storage, and RBAC to avoid plaintext or world‑readable web.yml files in artifacts.
  • Add CI gates to prevent artifacts from being published containing web.yml or unencrypted credentials. Fail builds that include sensitive files.
  • For Kubernetes: store credentials in Secrets (encrypted at rest by default) or external secret stores and avoid baking web.yml into images or ConfigMaps. Rotate secrets if in doubt.
1.) A minimal, prioritized remediation playbook
  • Inventory: list services that vendor or import github.com/prometheus/exporter-toolkit and note versions.
  • Patch: update to exporter‑toolkit v0.7.3 or v0.8.2 and rebuild artifacts. (github.com)
  • Restrict: place ingress filters and network ACLs in front of metric endpoints.
  • Rotate: change affected credentials if you detect exposure.
  • Validate: run integration tests exercising authentication and confirm logs show bcrypt runs (not cache-based bypassalerts for config exposure, unexpected reads of web.yml, and unusual auth sequences.

Risk analysis: who should be most worried​

  • Public-facing exporter endpoints that rely solely on web.yml basic auth and run the vulnerable toolkit are at highest risk. If web.yml or bcrypt hashes are accessible in images, registries, or public storage, the attacker’s job becomes trivial. (github.com)
  • Environments that bake configs into images (CI artifacts, container images stored in registries, or Helm charts in public repositories) are particularly vulnerable because hashes can leak widely.
  • Managed Kubernetes environments or cloud offerings that expose monitoring stacks to tenants without strict separation should review whether vendor packaging included the vulnerable module; many downstream vendors produced advisories and package updates.
It’s worth noting a systemic lesson: observability tooling and its helper libraries matter to security. Earlier Prometheus/OpenTelemetry advisories demonstrated that instrumentation can itself become an attack surface (for example, unbounded metric cardinality DoS issues). CVE‑2022‑46146 is a complementary reminder that even small helper libraries that handle auth must be audited as part of supply‑chain security.

Supply‑chain and vendor mapping: checklists for operators​

Because many vendors and distributions repackage or vendor the exporter toolkit, you must verify your vendor stack rather than just your top-level code:
  • Search your artifacts (images, binary bundles, vendor folders) for the module name github.com/prometheus/exporter-toolkit and the module versions.
  • Check distribution advisories (your Linux distro, Kubernetes distributions, or managed service vendor) to see whether they shipped patched packages or if they will not fix a particular downstream packaging. Many vendors published mapping and patches in late 2022 and into 2023; confirm that your vendor’s packages contain the upstream fix or a backport. (cvedetails.com)
Suggested audit queries and commands (conceptual)
  • Search code bases and containers for "github.com/prometheus/exporter-toolkit" or "web.yml".
  • Inspect go.mod files or vendor directories to find explicit versions.
  • For binaries that you cannot rebuild immediately, use tools that extract module metadata from compiled Go binaries to confirm embedded module versions.

Practical detection queries and monitoring ideas​

  • Alert on image builds that include "web.yml" files or bcrypt pattern strings like "$2y$".
  • In access logs, detect sudden successful authentications from IPs that previously failed password checks or from clients that only ever present single unusual token sequences prior to success.
  • Add file‑integrity monitors on locations that store web.yml to detect unexpected reads or downloads.
  • Add Prometheus/Grafana dashboards to show authentication success/failure ratios over time; an abrupt shift from repeated failures to success for a client should trigger investigation.

Broader lessons and developer guidance​

  • Treat secrets and secret placeholders as high‑risk artifacts in any CI/CD pipeline. Do not bake or commit web.yml files into images or code repositories.
  • Defensive coding for authentication: caches that optimize cryptographic checks must have succinct, unambiguous keys and conservative semantics. Never allow cache entries produced under a failure path to be interpreted as success. Test for cache collisions and ambiguous concatenations. The exporter‑toolkit fix uses hex encoding and explicit separators—simple but effective hardening. (github.com)
  • Add tests that simulate adversarial input and cache poisoning scenarios; unit tests are the easiest way to prevent regressions. The maintainer’s patch included a test case for CVE‑2022‑46146. (github.com)

Final verdict: what operators must do right now​

  • If you run any service that uses the Prometheus exporter‑toolkit, identify the module version immediately and upgrade to one of the patched releases (0.7.2/0.7.3/0.8.2). Rebuild and redeploy all artifacts that include the vulnerable library. This is the definitive, first‑order remediation. (github.com)
  • Assume that any web.yml or bcrypt hashes found in public or weakly protected places are compromised. Rotate the credentials and ensure new hashes are generated in a secured secret store. Restrict access to metrics endpoints during the remediation window. (github.com)
  • Harden your CI/CD and artifact hygiene to never publish or bake secret configuration files into public images or registries. Add detection to your pipeline to catch web.yml patterns, bcrypt strings, and vendor module versions prior to publishing.
This vulnerability is a concrete example of how small implementation mistakes in helper libraries can become big operational risks when secrets leak. The patch is straightforward and tested; the operational work is inventory, patch, rebuild, and rotation. Treat the fix as a high‑priority item for any environment that relies on exporter-toolkit-based basic authentication, and treat exposure of bcrypt hashes as a first‑class incident. (github.com)

Conclusion
CVE‑2022‑46146 is not a theoretical flaw: it converts the practical problem of leaked bcrypt hashes into an immediate bypass of basic authentication via cache poisoning. The exporter‑toolkit maintainers fixed the bug with conservative, well‑tested changes; operators who apply the patches, remove exposed web.yml files from images and artifacts, and rotate exposed credentials will eliminate the immediate risk. For longer-term resilience, teams must add dependency inventory and secrets‑hygiene controls, harden ingress to metrics endpoints, and treat observability libraries with the same security scrutiny as any other network-facing code. (github.com)

Source: MSRC Security Update Guide - Microsoft Security Response Center
 

Back
Top