Skip to content

UID2-7800, UID2-7801: suppress 2 CVEs in .trivyignore - #426

Merged
swibi-ttd merged 1 commit into
mainfrom
swi-suppress-20260902-114826
Sep 2, 2026
Merged

UID2-7800, UID2-7801: suppress 2 CVEs in .trivyignore#426
swibi-ttd merged 1 commit into
mainfrom
swi-suppress-20260902-114826

Conversation

@swibi-ttd

Copy link
Copy Markdown
Contributor

Suppresses 2 vulnerabilities in .trivyignore, expiry 2026-12-02 (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-66046 — HIGH, libexpat (Alpine base-image OS library)

The CVE is a quadratic-complexity DoS in native Expat's storeAtts() (xmlparse.c), exploitable only when an application parses attacker-supplied XML through expat. libexpat 2.8.3-r0 is present in every flagged repo solely as a transitive OS package of its Alpine base image (eclipse-temurin:21-jre-alpine-3.23 for the five Java services, python:3.x-alpine3.23 for snowflake). The five Java services are pure-Java Vert.x apps: they parse XML through the JVM's JAXP/Xerces stack, not native libexpat, and contain no System.loadLibrary/JNI/native XML bindings — the only XML on disk is trusted logback/config. snowflake is Python where libexpat backs CPython's pyexpat, but its scripts (token/key/salt generators, Snowflake monitoring) import no XML module and never parse untrusted XML. With no code path feeding untrusted XML into expat in any repo, the vulnerable storeAtts() scan is unreachable everywhere. A fixed version (2.8.4-r0) exists but does not change the not_affected verdict.

Full triage report — CVE-2026-66046

CVE-2026-66046 — libexpat quadratic-complexity DoS in storeAtts()

Severity: HIGH (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/…)
Package: libexpat 2.8.3-r0 → fixed 2.8.4-r0
Verdict: not_affected (suppress)

What the CVE is

Expat through 2.8.3 has a denial-of-service caused by quadratic (O(N²)) algorithmic complexity in storeAtts() in xmlparse.c. Processing N specified attributes with non-normalized values triggers a linear scan of elementType->defaultAtts per attribute to determine CDATA status. A remote unauthenticated attacker can supply one well-formed multi-megabyte XML document to an application that parses untrusted XML through expat, causing excessive CPU. No auth, external-entity resolution, or non-default parser options required.

How it reaches (or doesn't reach) our services

libexpat 2.8.3-r0 was flagged in all six repos, but in every case it is present only as a transitive OS package of the Alpine base image, not as a declared dependency:

  • uid2-admin, uid2-core, uid2-operator, uid2-optout, uid2-validator — pure-Java Vert.x services built FROM eclipse-temurin:21-jre-alpine-3.23. These parse XML through the JVM's JAXP/Xerces implementation, which is Java, not native libexpat. Source search found no System.loadLibrary/JNI/native XML bindings and no expat references. The only XML present is trusted conf/logback.xml configuration, never attacker-controlled input. The vulnerable native code path is never invoked.
  • uid2-snowflake — Python tooling built FROM python:3.x-alpine3.23. libexpat backs CPython's pyexpat, but the code (token/key/salt/email generators, Snowflake monitoring) imports no XML module (xml, lxml, etree, sax, minidom — all absent) and parses no untrusted XML. No path feeds attacker input into expat.

Because no repo passes untrusted XML into expat, the quadratic storeAtts() scan is unreachable across the board.

Decision

Reachability is broken in all six repos, so this is not_affected and should be suppressed, even though a fixed package (2.8.4-r0) exists. The base image will pick up the fix on the next routine rebuild; no code change is required. Suppression belongs in each repo's root .trivyignore.

Confidence: high — verdict rests on direct evidence (Dockerfile base images, absence of native XML linkage in Java sources, absence of any XML parsing of untrusted input in the Python code).

CVE-2026-76641 — HIGH, libexpat (Alpine base-image native C library)

CVE-2026-76641 is an out-of-bounds read in the native C library libexpat, triggered only when a process parses XML through expat's C API (specifically external entity parsers created via XML_ExternalEntityParserCreate). libexpat is present in the Alpine base image of all six flagged artifacts, but every scanned artifact (alpine 3.23.5) is an eclipse-temurin 21-jre-alpine Java image — including uid2-snowflake, whose scanned artifact is the Java ETL image (etl/Dockerfile), not its separate Python Dockerfiles. Java services parse XML via the JVM's own JAXP/Xerces implementation (pure Java), never linking to native libexpat. Grep found no System.loadLibrary/JNI usage and no native XML binding in any repo (the single loadLibrary/native regex hit was a false positive on the string "service name"). With no process invoking expat's C parser, the vulnerable code path cannot be exercised, so the finding is unreachable in all six repos regardless of the available fixed package.

Full triage report — CVE-2026-76641

CVE-2026-76641 — libexpat out-of-bounds read — Triage: NOT AFFECTED

Vulnerability

Expat through 2.8.3 contains an out-of-bounds read (introduced by the fix for CVE-2026-66046). A struct-size mismatch between ELEMENT_TYPE members causes storeAtts to read the attIndex member past allocated memory when processing XML with external entity parsers created via XML_ExternalEntityParserCreate, causing either failed whitespace normalization in non-CDATA attributes or a wild-pointer segfault. Severity HIGH; installed 2.8.3-r0, fixed in 2.8.4-r0.

Where it was found

libexpat is a native C library shipped in the Alpine base image (eclipse-temurin:21-jre-alpine-3.23) used by all six flagged repos. The scanner correctly reports its presence in the image filesystem.

Reachability analysis

The vulnerable code path only executes when a process parses XML through expat's C API. All six scanned artifacts (alpine 3.23.5) are pure-Java Vert.x/ETL services launched with java -jar:

  • uid2-admin, uid2-core, uid2-operator, uid2-optout, uid2-validatorFROM eclipse-temurin@sha256:319339... (21-jre-alpine-3.23); apk adds only libpng/libcrypto3/libssl3/musl/gnutls (crypto/PNG, never libexpat directly); no JNI or native XML binding.
  • uid2-snowflake — the scanned alpine 3.23.5 target is the Java ETL image (etl/Dockerfile, same temurin base, java -jar ... cronjob). Its Python Dockerfile.dev/Dockerfile.monitoring are separate images and were not the scanned artifact; regardless, no xml/pyexpat/ElementTree imports exist anywhere in the repo.

The JVM parses XML with its own JAXP/Xerces implementation (pure Java), which does not link to native libexpat. Source search found no System.loadLibrary, JNI, or native XML path in any repo (the one regex hit was a false positive on the literal string "service name"). No process in any image invokes expat's C parser, so XML_ExternalEntityParserCreate / storeAtts cannot be reached.

Decision

not_affected for all six repos. libexpat is present but unreachable — no native XML parsing path exists. Per triage policy, a not-exploitable CVE is suppressed even though a fixed package (2.8.4-r0) exists; the base-image bump will pick it up on the normal update cadence. Recommended action: suppress (repo-root .trivyignore).


Opened by uid2-vul-scan-agent (general_use_claude-opus-4-8) for the automated finding(s) above. Verdict confidence: high. Please sanity-check each reachability argument before approving.

- CVE-2026-66046 (UID2-7800)
- CVE-2026-76641 (UID2-7801)

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 bedbe4c into main Sep 2, 2026
5 checks passed
@swibi-ttd
swibi-ttd deleted the swi-suppress-20260902-114826 branch September 2, 2026 06:54
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