Skip to content

UID2-7662, UID2-7656: suppress 2 CVEs in .trivyignore - #2689

Merged
swibi-ttd merged 1 commit into
mainfrom
swi-suppress-20260811-110031
Aug 11, 2026
Merged

UID2-7662, UID2-7656: suppress 2 CVEs in .trivyignore#2689
swibi-ttd merged 1 commit into
mainfrom
swi-suppress-20260811-110031

Conversation

@swibi-ttd

Copy link
Copy Markdown
Contributor

Suppresses 2 vulnerabilities in .trivyignore, expiry 2026-11-11 (3 months). No code fixes — each is present in the image but not reachable from this service.

Reachability alone determines suppress-vs-fix: a fixed version existing upstream does not make an unreachable path exploitable. Change any expiry in review if you want a different window.

If another suppression PR is open on this repo, this one supersedes it. Each scan run raises a fresh branch carrying every outstanding suppression, so the newest PR is a superset of the older ones — merge this and close the rest rather than merging both, which would conflict on the same append.

CVE-2026-40984 — HIGH, io.micrometer:micrometer-core (transitive via micrometer-registry-prometheus/-jmx); micrometer-jetty11/12 not present

CVE-2026-40984 (GHSA-g3pr-3p32-fp23) is a DoS via metric tag/URI cardinality explosion in Micrometer's own HTTP SERVER instrumentation: micrometer-core's HTTP/servlet binder, micrometer-jetty11 and micrometer-jetty12. All UID2 Java services are Vert.x/Netty (no Jetty anywhere; micrometer-jetty11/12 are not dependencies). They instrument HTTP through io.vertx.micrometer (vertx-micrometer-metrics), which computes HTTP tags itself and only publishes into a Micrometer registry; application code uses solely Micrometer core primitives (Counter/Gauge/Timer/Metrics/PrometheusMeterRegistry). No code imports micrometer.core.instrument.binder.http or any servlet/Jetty tag provider, so the vulnerable HTTP-server binder path is never exercised. micrometer-core is present transitively (via micrometer-registry-prometheus/-jmx) which is why the scanner flags it, but present != reachable. The portal is a Node app with no micrometer of its own; its Keycloak base image is third-party and also uses Vert.x/Quarkus HTTP instrumentation. Reachability chain is broken for every repo, so the finding is not exploitable and should be suppressed regardless of available fixes.

Full triage report — CVE-2026-40984

CVE-2026-40984 — Micrometer HTTP server instrumentation DoS — UID2 Impact Assessment

Summary

  • CVE: CVE-2026-40984 / GHSA-g3pr-3p32-fp23 — "Micrometer HTTP server instrumentations DoS"
  • Severity: HIGH — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (availability only)
  • Weakness: CWE-400 / CWE-770 — uncontrolled resource consumption. Specially crafted HTTP requests cause unbounded metric tag/URI cardinality, exhausting memory and producing a DoS.
  • Affected modules: io.micrometer:micrometer-core (its HTTP/servlet server-instrumentation binder), io.micrometer:micrometer-jetty11, io.micrometer:micrometer-jetty12.
  • Fixed in: 1.9.18, 1.13.19, 1.14.16, 1.15.11.1, 1.16.5.1 (core/jetty lines 1.13.16 / 1.14.15 / 1.15.12 / 1.16.6).

What we ship

Micrometer appears in all five Java repos:

Repo micrometer version How HTTP metrics are wired
uid2-core 1.12.2 io.vertx.micrometer (Vert.x)
uid2-admin 1.12.2 io.vertx.micrometer (Vert.x)
uid2-operator 1.12.2 io.vertx.micrometer (Vert.x)
uid2-optout 1.1.0 io.vertx.micrometer (Vert.x)
uid2-validator 1.12.2 io.vertx.micrometer (Vert.x)
uid2-self-serve-portal n/a (Node app)

Dependencies present are vertx-micrometer-metrics, micrometer-registry-prometheus, and micrometer-registry-jmx. micrometer-core is pulled in transitively by those registries — which is why the scanner flags it — but micrometer-jetty11/micrometer-jetty12 are absent from every pom, and there is no Jetty anywhere in the codebase.

Reachability analysis

The CVE is specifically about Micrometer's own HTTP server instrumentation — the servlet/HTTP binder (and the Jetty modules) that turn incoming request URIs into metric tags. That is the code where an attacker-controlled, high-cardinality path floods the meter registry.

Our services do not use that path:

  1. HTTP instrumentation is Vert.x's, not Micrometer's. Every service configures io.vertx.micrometer.MicrometerMetricsOptions + VertxPrometheusOptions (e.g. uid2-operator/Main.java:495 sets Label.HTTP_METHOD/HTTP_CODE/HTTP_PATH/POOL_NAME). Vert.x computes these HTTP tags in its own metrics SPI and merely publishes them into a Micrometer registry. Micrometer's vulnerable HTTP-server binder is never invoked.
  2. Application code uses only Micrometer core primitivesCounter, Gauge, Timer, Metrics, PrometheusMeterRegistry. A grep for the vulnerable binders (micrometer.core.instrument.binder.http, HttpServletRequestTagsProvider, JettyConnectionMetrics, TimedHandler, jetty11/12) returns zero matches across all repos.
  3. No Jetty/servlet stack. These are Vert.x-on-Netty services; the Jetty-specific vulnerable modules are not even on the classpath.
  4. Portal. uid2-self-serve-portal is a node:20-alpine app with no Micrometer in its own dependencies. Its only Java-adjacent artifact is the third-party quay.io/keycloak/keycloak:26.6.4 image, which runs on Quarkus and likewise instruments HTTP via Vert.x rather than Micrometer's Jetty/servlet binders.

Because the request-handling path never flows through the affected Micrometer HTTP-server instrumentation, the cardinality-explosion trigger cannot be reached, and the availability impact does not apply to our deployment.

Decision

not_affected for all six repos. The package is present (transitively) but the vulnerable code path is unreachable. Per policy, a not-exploitable finding is suppressed even though fixed versions exist — recommend adding a suppression in the repo-root .trivyignore of each affected repo.

If Micrometer HTTP-server binders or the micrometer-jetty11/12 modules are ever introduced (e.g. a future migration off Vert.x metrics), this verdict must be revisited — at that point simply upgrading Micrometer to a fixed version would be the remedy.

Confidence: high for the Java services (direct code + dependency evidence). The portal conclusion rests on it being a Node app plus a third-party Quarkus/Vert.x-based Keycloak image, which does not use the vulnerable binders.

CVE-2026-56408 — HIGH, libexpat (Alpine base image, transitive via eclipse-temurin:21-jre-alpine-3.23)

Integer overflow (CWE-190) in native libexpat's copyString(), reachable only by parsing XML through the libexpat C library. libexpat is present solely as a transitive OS dependency of the eclipse-temurin:21-jre-alpine-3.23 base image (font/fontconfig chain); no repo installs or links it. All five services are pure-Java Vert.x apps that parse XML via the JVM's JAXP/Xerces stack, not native libexpat, and contain no JNI bindings or loadLibrary calls to it. The advisory's local XML-parsing vector cannot be exercised through our build/run configuration, so the vulnerable path is unreachable despite the library being present.

Full triage report — CVE-2026-56408

CVE-2026-56408 — libexpat integer overflow in copyString

What the CVE is

libexpat before 2.8.2 contains an integer overflow (CWE-190) in the internal copyString() routine. It is reached when the native libexpat C library parses XML input; the OSV/NVD vector is CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L (local, high attack complexity). Fixed in libexpat 2.8.2 (Alpine 2.8.2-r0).

What was scanned

The findings come from the container images built by each repo's Dockerfile, all of which are FROM eclipse-temurin@sha256:... = eclipse-temurin:21-jre-alpine-3.23. libexpat 2.8.1-r0 ships in that base image as a transitive OS dependency (font-rendering chain: fontconfig → freetype/expat). No repo declares or installs it.

How it affects our services — code search

  • No explicit install: none of the five Dockerfiles apk add libexpat. They add only libpng libcrypto3 libssl3 musl musl-utils gnutls (admin/core/optout), gcompat (operator), or nothing extra (validator).
  • No native path: a repo-wide search for expat, libexpat, XML_Parse, JNI, System.loadLibrary, and native across *.java/*.c/*.cpp/*.h/*.xml returned zero matches.
  • Pure-Java XML: all five are Vert.x/Java services on the JVM. The only XML they handle (logback.xml, conf/*.xml) is parsed by the JVM's JAXP/Xerces implementation — pure Java — never by native libexpat.
  • Nitro builders (operator, validator) are FROM ubuntu:22.04 and are build-only stages; they are not the alpine runtime artifacts the scanner inspected.

Because these services never invoke libexpat through any JNI/native binding, the advisory's XML-parsing overflow path is not reachable in the way we build and run the artifacts.

Decision

not_affected for all five repos (uid2-admin, uid2-core, uid2-operator, uid2-optout, uid2-validator). The package is present in the base image (the scan is correct) but unreachable — consistent with the standing rule that Alpine base-image OS libraries are presumed unreachable for pure-Java services absent a demonstrated native path, which does not exist here.

Recommended action

Suppress this finding in each repo's root .trivyignore. A fixed package (2.8.2-r0) exists and will arrive naturally when the base image is bumped, but the fix does not change the not_affected verdict; suppression is appropriate because the path is not exploitable in our services. Confidence: high.


Opened by uid2-vul-scan-agent (general_use_claude-opus-4-8), verdict confidence high. Please sanity-check each reachability argument before approving.

- CVE-2026-40984 (UID2-7662)
- CVE-2026-56408 (UID2-7656)

Each is present but not reachable from this service; see the linked tickets for the per-CVE impact assessments. Reachability alone determines suppress-vs-fix.
@swibi-ttd
swibi-ttd merged commit ad02d42 into main Aug 11, 2026
10 checks passed
@swibi-ttd
swibi-ttd deleted the swi-suppress-20260811-110031 branch August 11, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants