Reachable Risk sample reports

spring-petclinic-microservices @ 3858f9c (Spring Boot 4.0.1, Spring Cloud 2025.1.0)

691 open dependency alerts across the eight Spring Boot services of the distributed Spring PetClinic, scored in the execution context each service runs in. 109 need scheduling; two carry an unresolved question.

Run date
2026-09-03
Scale
691 alerts, 691 context-specific verdicts, 3 execution contexts (gateway, services, platform) across 8 services
Rubric
2026.08.24-v27
Workflow
2026.09.03-v34
Scored by
claude-opus-5
Risk context
2026-09-02+3858f9c
SLA policy
SafeCo Vulnerability Management Policy (ISP-07) v1.0 (fictional stand-in)

Report (Markdown)risk-context.yaml (the context we gather together)

The SLA policy is a fictional stand-in so the samples stay comparable; deadlines in a real run come from your own vulnerability management policy. The published risk-context.yaml is a copy of the run file with prose comments edited for publication; every declared context, path, asset context, actor and deployment fact is identical. After the run, k9's hand adjudication resolved both REVIEW verdicts (GHSA-2m67-wjpj-xhg9 on customers-service and visits-service) to DEFER: the advisory defeats a configured parser limit, and this project configures none, so the broken enforcement changes nothing an attacker can observe. Upgrading would close the alert without changing the deployment's behavior. The adjudication also caught a miss: the report defers CVE-2026-29062 on the same two services, but an anonymous JSON request that declares a non-Unicode charset reaches the vulnerable parser through a branch of Spring's request handling that no model run read. That is why k9 adjudicates model runs by hand and reports the result next to the sample, misses included.

Dependency Alert Triage Report - spring-petclinic-microservices - 2026-09-03

Executive Summary

Evidence is complete on 689 of 691 open alerts: nothing needs to be fixed today, 109 are recommended for a scheduled fix, and 580 (83.9%) are recommended for deferral with the evidence below. Evidence is incomplete on 2: tools.jackson.core:jackson-core GHSA-2m67-wjpj-xhg9, in customers-service and visits-service, needs a person to decide fix-or-defer. Resolve those two first.

Every open alert was retrieved and the count verified at 691, and each one was analyzed for reachability against this project's own code, its vendored dependency sources, and the deployment facts committed in .k9security/risk-context.yaml. Exploitation evidence came from KEV (the CISA/VulnCheck catalog of vulnerabilities with confirmed exploitation in the wild) and EPSS (a daily model score estimating each vulnerability's probability of exploitation in the next 30 days, read as a percentile against all scored CVEs).

How many findings are exploitable and reachable in production right now? Zero. No alert in this set is listed in KEV, and none carries an EPSS score in the top 1%. Nothing meets the rubric's bar for immediate action.

How much noise did scoring remove? 83.9%. 580 of the 691 open alerts scored are recommended for deferral as not reachable or not exploitable in this deployment. Every open alert was scored, deferrals included, so the denominator is the full set. Attention can be directed elsewhere for those 580.

The SafeCo ISP-07 policy dates its clock from the day an alert was opened in the tracking tool, and the supplied alert records carry no open date. No SLA expiry date could be computed for any finding, so this report gives each finding its policy window instead: 30 days for the two REVIEW findings, 60 days for the 23 Moderate-residual findings, 180 days for the remaining 666. Supply alert open dates and the expiry dates resolve automatically.

The reachability and exploitability analysis retired 40,650 of 55,280 inherent NIST risk points (73.5%), safely deferred 580 of 691 findings, and moved 666 findings from a High inherent band to a Low residual band.

Bucket Count Meaning
FIX_TODAY 0 Fix now
REVIEW 2 Unresolved question; investigate before deciding
SCHEDULE 109 Fix on a planned horizon; SLA below
DEFER 580 No action needed; evidence below

Start with the two REVIEW findings, which are the only place the analysis could not finish. Then take the 18 SCHEDULE findings with a traced path to attacker-controlled input; the other 91 SCHEDULE findings are unreachable and carry a scheduled verdict only because they sit on the internet-facing gateway. The 580 deferral recommendations are evidence-backed below.

FIX_TODAY / REVIEW: act now or resolve the unknown

No finding requires action today. Two findings carry an unresolved question.

REVIEW is the rubric declining to overclaim. On these two the evidence supports neither "fix" nor "safe to defer", so a person resolves the unknown. That is an honest result, not a defect in the analysis, and a REVIEW must not be dismissed: dismissing it would convert "we do not know" into "we decided it is fine". A fixed release of tools.jackson.core:jackson-core exists, and upgrading may cost less than investigating; whether it does depends on your code and your release schedule, so that call is yours.

GHSA-2m67-wjpj-xhg9 — unbounded document length in the Jackson 3 streaming parser — REVIEW

  • Finding: maven:tools.jackson.core:jackson-core:GHSA-2m67-wjpj-xhg9:customers, maven:tools.jackson.core:jackson-core:GHSA-2m67-wjpj-xhg9:visits (tools.jackson.core:jackson-core 3.0.3, transitive via spring-boot-starter-web; spring-petclinic-customers-service/pom.xml, spring-petclinic-visits-service/pom.xml). Two locations.
  • Why REVIEW: the threat evidence is missing, and reachability is determined and positive. GHSA-2m67-wjpj-xhg9 carries no CVE alias, so no KEV record and no EPSS score exist for it; the factor has no signal at all, rather than a low one. Exposure is present: both services deserialize anonymous request bodies through Jackson 3's blocking and non-blocking parsers, so a caller controls the document the parser reads. Impact is present on a tier_2 production asset.
  • Residual risk: High, 80/100 (inherent High 80; 0 points retired), low confidence.
  • SLA expiry: ? (30-day window). The policy applies; its clock starts at the alert open date, which the supplied alert records do not contain. The clock here runs on resolving the unknown, not on shipping a fix.
  • Evidence: not listed in KEV. No EPSS score is published for this advisory, and none is published for its unaliased identifier, so the threat factor is genuinely unknown rather than confidently absent. Reachability was determined by reading the call graph: request bodies arriving at the customers-service and visits-service REST controllers reach tools.jackson.core parser entry points with no length ceiling configured in either service. The retired: 0 beside a low confidence marker is the signature of an unfinished analysis, reported as such.
  • What resolves it: a CVE assignment for GHSA-2m67-wjpj-xhg9, or an EPSS score for it once assigned. Either turns the Threat factor from unknown into a measured value, at which point the finding scores as SCHEDULE (threat absent) or FIX_TODAY (threat present) without further work.

SCHEDULE: fix on a planned horizon

Here is what the analysis found. On 18 of these findings a call path was traced from an anonymous internet caller to the vulnerable code, so exposure is a found fact. On the other 91 the vulnerable code is not reachable at all; those carry a scheduled verdict because the public_asset_floor applies to spring-petclinic-api-gateway, which the risk-context file declares as public_unauth and which the trust model says an anonymous internet user reaches on every route. None of the 109 is listed in KEV. Every one carries an EPSS score below the p99 top-1% line, and all but two sit below p90; the two gray-zone members are named at the end of the DEFER section. No SLA expiry date is computable, so entries are ordered by residual composite descending, then by package.

The traced findings come first.

GHSA-38f8-5428-x5cv (CVE-2026-42585) — HTTP request smuggling via malformed request-line handling — SCHEDULE

  • Finding: maven:io.netty:netty-codec-http:GHSA-38f8-5428-x5cv:gateway (io.netty:netty-codec-http 4.2.9.Final, transitive via spring-cloud-starter-gateway-server-webflux and Reactor Netty; spring-petclinic-api-gateway/pom.xml).
  • Why SCHEDULE: exposure is present as a traced fact, not an inference. The gateway terminates HTTP/1.1 from the internet on Reactor Netty, and the vulnerable Netty decoder parses the request line of every anonymous request. Threat is absent, impact is present on a tier_2 production asset.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window). Policy clock starts at the alert open date; the supplied records carry none.
  • Evidence: not listed in KEV. EPSS percentile 15.98 with a raw score of 0.00248, far below the p99 top-1% line. Reachability was established by reading the call graph (manual_call_graph): spring-petclinic-api-gateway runs Reactor Netty as its server, .k9security/risk-context.yaml marks it public_unauth with anonymous-internet-user reaching every route, and the gateway performs its own HTTP/1.1 framing normalization on the way to backends, which means the vulnerable decoder runs on attacker-supplied bytes at the front door.
  • Recommended action: raise the Netty version this build resolves. Netty ships as a managed dependency of the Spring Boot 4.0.1 BOM, so set the netty.version property in the parent POM to the fixed 4.2.x release named in the advisory, which pulls every io.netty:* artifact in lockstep and clears the other seven traced Netty findings below at the same time.

GHSA-m4cv-j2px-7723 (CVE-2026-42580) — HTTP request smuggling via header handling — SCHEDULE

  • Finding: maven:io.netty:netty-codec-http:GHSA-m4cv-j2px-7723:gateway (io.netty:netty-codec-http 4.2.9.Final, transitive; spring-petclinic-api-gateway/pom.xml).
  • Why SCHEDULE: exposure is present as a traced fact. The vulnerable header path runs on every anonymous HTTP/1.1 request the gateway accepts. Threat is absent, impact is present on a tier_2 production asset.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window).
  • Evidence: not listed in KEV. EPSS percentile 29.41, raw score 0.00364. Reachability by traced call graph: Reactor Netty's HTTP/1.1 server decoder on the gateway's public listener.
  • Recommended action: covered by the same netty.version bump described above; no separate change is needed.

GHSA-pwqr-wmgm-9rr8 (CVE-2026-33870) — control characters accepted in HTTP/1.1 framing — SCHEDULE

  • Finding: maven:io.netty:netty-codec-http:GHSA-pwqr-wmgm-9rr8:gateway (io.netty:netty-codec-http 4.2.9.Final, transitive; spring-petclinic-api-gateway/pom.xml).
  • Why SCHEDULE: exposure is present as a traced fact. The gateway is the HTTP/1.1 termination point for anonymous internet traffic and re-encodes framing toward backends, so the vulnerable decoder sees raw attacker bytes. Threat is absent, impact is present.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window).
  • Evidence: not listed in KEV. EPSS percentile 48.30, raw score 0.00640. Reachability by traced call graph.
  • Recommended action: covered by the same netty.version bump.

GHSA-xxqh-mfjm-7mv9 (CVE-2026-42581) — HTTP/1.1 pipelining desynchronization — SCHEDULE

  • Finding: maven:io.netty:netty-codec-http:GHSA-xxqh-mfjm-7mv9:gateway (io.netty:netty-codec-http 4.2.9.Final, transitive; spring-petclinic-api-gateway/pom.xml).
  • Why SCHEDULE: exposure is present as a traced fact. Pipelined requests from an anonymous caller are decoded by the vulnerable path on the gateway's public listener. Threat is absent, impact is present.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window).
  • Evidence: not listed in KEV. EPSS percentile 47.86, raw score 0.00630. Reachability by traced call graph.
  • Recommended action: covered by the same netty.version bump.

GHSA-hvcg-qmg6-jm4c (CVE-2026-50020) — HTTP/1.1 decoder state confusion — SCHEDULE

  • Finding: maven:io.netty:netty-codec-http:GHSA-hvcg-qmg6-jm4c:gateway (io.netty:netty-codec-http 4.2.9.Final, transitive; spring-petclinic-api-gateway/pom.xml).
  • Why SCHEDULE: exposure is present as a traced fact on the public HTTP/1.1 listener. Threat is absent, impact is present.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window).
  • Evidence: not listed in KEV. EPSS percentile 13.97, raw score 0.00232. Reachability by traced call graph.
  • Recommended action: covered by the same netty.version bump.

GHSA-v8h7-rr48-vmmv (CVE-2026-41417) — request URI handling in the Netty HTTP client — SCHEDULE

  • Finding: maven:io.netty:netty-codec-http:GHSA-v8h7-rr48-vmmv:gateway (io.netty:netty-codec-http 4.2.9.Final, transitive; spring-petclinic-api-gateway/pom.xml).
  • Why SCHEDULE: exposure is present as a traced fact, and this one is client-side rather than server-side. Reactor Netty's HttpClientConnect passes the caller-influenced path and query straight through at vendor/reactor-netty-http-1.3.1/reactor/netty/http/client/HttpClientConnect.java:569, and the gateway builds its proxied request URI from the anonymous caller's own path. Threat is absent, impact is present.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window).
  • Evidence: not listed in KEV. EPSS percentile 22.95, raw score 0.00307. Reachability by traced call graph, with the propagating call site read and recorded above.
  • Recommended action: covered by the same netty.version bump.

GHSA-q4f6-jm68-57ww (CVE-2026-59899) — HTTP/1.1 request decoding defect — SCHEDULE

  • Finding: maven:io.netty:netty-codec-http:GHSA-q4f6-jm68-57ww:gateway (io.netty:netty-codec-http 4.2.9.Final, transitive; spring-petclinic-api-gateway/pom.xml).
  • Why SCHEDULE: exposure is present as a traced fact on the public HTTP/1.1 listener. Threat is absent, impact is present.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window).
  • Evidence: not listed in KEV. EPSS percentile 26.18, raw score 0.00335. Reachability by traced call graph.
  • Recommended action: covered by the same netty.version bump.

GHSA-rwm7-x88c-3g2p (CVE-2026-42577) — connection reset handling in the epoll transport — SCHEDULE

  • Finding: maven:io.netty:netty-transport-classes-epoll:GHSA-rwm7-x88c-3g2p:gateway (io.netty:netty-transport-classes-epoll 4.2.9.Final, transitive; spring-petclinic-api-gateway/pom.xml).
  • Why SCHEDULE: exposure is present as a traced fact. The gateway runs on Linux containers built from eclipse-temurin:17, so Netty selects the epoll transport, and an anonymous caller can reset a connection at will against the public listener. Threat is absent, impact is present.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window).
  • Evidence: not listed in KEV. EPSS percentile 33.97, raw score 0.00408. Reachability by traced call graph, including the docker/Dockerfile base image that makes the native epoll transport the one actually selected at runtime.
  • Recommended action: covered by the same netty.version bump.

GHSA-g3pr-3p32-fp23 (CVE-2026-40984) — unbounded metric tag cardinality in Micrometer — SCHEDULE

  • Finding: maven:io.micrometer:micrometer-core:GHSA-g3pr-3p32-fp23:gateway, :customers, :vets, :visits, :genai (io.micrometer:micrometer-core 1.16.1, transitive via spring-boot-starter-actuator; the five module POMs). Five locations.
  • Why SCHEDULE: exposure is present as a traced fact in all five services. Each auto-configures the Spring Boot HTTP server metrics binder, which derives tag values from request attributes an anonymous caller controls, and none of the five caps tag cardinality. The gateway location additionally sits on a public_unauth asset. Threat is absent, impact is present on tier_2 production assets.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window).
  • Evidence: not listed in KEV. EPSS percentile 52.94, raw score 0.00763. Reachability by traced call graph in each of the five services. The same advisory scores DEFER on config-server, discovery-server, and admin-server, where the only metric-tag inputs come from operators and from the internal service mesh; those three locations have no attacker-controlled input, which is the discriminating difference.
  • Recommended action: raise the Micrometer version this build resolves by setting micrometer.version in the parent POM to the fixed 1.x release named in the advisory. As a configuration-only alternative that does not require an upgrade, set an explicit tag-cardinality limit on the HTTP server metrics binder so unbounded values cannot create unbounded time series.

GHSA-cjpg-rgq5-fr37 (CVE-2026-41853) — multipart request parsing defect in Spring Web MVC — SCHEDULE

  • Finding: maven:org.springframework:spring-webmvc:GHSA-cjpg-rgq5-fr37:customers, :vets, :visits (org.springframework:spring-webmvc 7.0.2, transitive via spring-boot-starter-web; the three service POMs). Three locations.
  • Why SCHEDULE: exposure is present as a traced fact. All three services run Tomcat with Spring MVC, and vendor/spring-boot-servlet-4.0.1/.../MultipartProperties.java leaves resolveLazily at its false default, so multipart bodies are parsed eagerly on arrival, before any handler decides whether it wants them. The gateway routes anonymous traffic to all three. Threat is absent, impact is present.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window).
  • Evidence: not listed in KEV. EPSS percentile 8.21, raw score 0.00186. Reachability by traced call graph, with the eager-parse default read from the vendored Spring Boot source. The same advisory scores DEFER on config-server and discovery-server, which take no request bodies from untrusted callers, and on genai-service and admin-server, where Spring MVC is on the classpath but WebFlux is the active web stack.
  • Recommended action: raise the Spring Framework version this build resolves by setting spring-framework.version in the parent POM to the fixed 7.0.x release named in the advisory. As an interim mitigation that does not require an upgrade, set spring.servlet.multipart.resolve-lazily=true in the three services so multipart bodies are parsed only when a handler asks for them.

GHSA-q62f-h9x2-gcqc (CVE-2026-41712) — chat memory shared across users under the default conversation id — SCHEDULE

  • Finding: maven:org.springframework.ai:spring-ai-client-chat:GHSA-q62f-h9x2-gcqc:genai, maven:org.springframework.ai:spring-ai-model:GHSA-q62f-h9x2-gcqc:genai (org.springframework.ai:spring-ai-client-chat and spring-ai-model 2.0.0-M1, direct; spring-petclinic-genai-service/pom.xml). Two locations.
  • Why SCHEDULE: exposure is present as a traced fact, and this is the one finding in the set with a data-confidentiality consequence rather than an availability one. PetclinicChatClient builds MessageChatMemoryAdvisor.builder(chatMemory).order(10).build() with no conversation id supplied, and exposes @PostMapping("/chatclient") String exchange(@RequestBody String query). Every caller therefore shares the advisory's DEFAULT_CONVERSATION_ID, so one user's prompts and the model's replies enter the next user's context window. The gateway routes anonymous internet traffic to this endpoint. Threat is absent, impact is present.
  • Residual risk: Moderate, 50/100 (inherent High 80; 30 points retired).
  • SLA expiry: ? (60-day window).
  • Evidence: not listed in KEV. EPSS percentile 17.48, raw score 0.00260. Reachability by traced call graph, with the advisor construction and the controller mapping both read in spring-petclinic-genai-service/src/main/java/.../PetclinicChatClient.java.
  • Recommended action: pass a per-user or per-session conversation id into the chat memory advisor rather than relying on the default, which fixes the cross-user leak without any dependency change. Separately, spring-ai is pinned at the 2.0.0-M1 milestone; moving to the fixed release named in the advisory closes it in the library as well.

The 91 unreachable findings on the public gateway

These 91 alerts are all on spring-petclinic-api-gateway. On every one of them the analysis determined that the vulnerable code cannot be reached: it is not delivered, not reachable from any entry point, gated behind an advisory precondition this deployment does not meet, or reached only with values the gateway itself produces. They carry a SCHEDULE verdict rather than DEFER for one reason: the public_asset_floor. The risk-context file declares this service public_unauth, tier_2, production, and its trust model names anonymous-internet-user as reaching every gateway route, so the rubric refuses to fully discount exposure on this asset even when reachability is negative. That floor is the driver, and it is the whole difference between these 91 and their identical siblings on the internal services, which score DEFER.

Because reachability is negative on all 91, they share one score: residual Low, 20/100 (inherent High 80; 60 points retired), and one policy window: ? (180-day window). None is in KEV. All but two carry an EPSS percentile below p90; the exceptions are guava GHSA-mvr2-9pj6-7w5j at p91.81 (raw 0.05119) and httpclient GHSA-7r82-7xv7-xcpj at p94.92 (raw 0.09032), both in the p90 to p99 gray zone and both unreachable here.

The recommended action for the whole group is one change, not 91: bring the gateway's managed dependency versions up with the parent POM's Spring Boot, Spring Cloud, and netty.version properties on the project's normal upgrade cadence. That is a maintenance action, not a security fix; none of these 91 is exploitable in this deployment today.

Package (all in spring-petclinic-api-gateway/pom.xml) Advisories Reachability finding
org.bouncycastle:bcprov-jdk18on GHSA-574f-3g2m-x479, GHSA-c3fc-8qff-9hwx vulnerable code not loaded
commons-configuration:commons-configuration GHSA-pvp8-3xj6-8c6x no attacker-controlled input
commons-lang:commons-lang GHSA-j288-q9x7-2f5v no attacker-controlled input
com.google.guava:guava GHSA-5mg8-w23w-74h3, GHSA-7g45-4rm6-3mm3, GHSA-mvr2-9pj6-7w5j unreachable from any entry point
org.apache.httpcomponents:httpclient GHSA-7r82-7xv7-xcpj no attacker-controlled input
org.apache.httpcomponents.client5:httpclient5 GHSA-hjcp-jmpx-g3qm no attacker-controlled input
org.apache.httpcomponents.core5:httpcore5 GHSA-hf6x-8p5f-cgmf no attacker-controlled input
org.apache.httpcomponents.core5:httpcore5-h2 GHSA-v3jc-474w-2wm6 unreachable from any entry point (HTTP/2 disabled)
com.fasterxml.jackson.core:jackson-core GHSA-72hv-8253-57qq, GHSA-r7wm-3cxj-wff9 unreachable from any entry point
tools.jackson.core:jackson-core GHSA-2m67-wjpj-xhg9, GHSA-72hv-8253-57qq, GHSA-r7wm-3cxj-wff9 (no attacker-controlled input); GHSA-6v53-7c9g-w56r (unreachable) see cell
com.fasterxml.jackson.core:jackson-databind GHSA-3pjw-73gf-8qr5, GHSA-5jmj-h7xm-6q6v (no attacker-controlled input); GHSA-hgj6-7826-r7m5, GHSA-j3rv-43j4-c7qm, GHSA-rmj7-2vxq-3g9f (unreachable) see cell
tools.jackson.core:jackson-databind GHSA-3pjw-73gf-8qr5, GHSA-5gvw-p9qm-jgwh, GHSA-5hh8-q8hv-fr38, GHSA-9fxm-vc8v-hj55, GHSA-rcqc-6cw3-h962 (no attacker-controlled input); GHSA-hgj6-7826-r7m5, GHSA-j3rv-43j4-c7qm, GHSA-rmj7-2vxq-3g9f (unreachable) see cell
org.apache.logging.log4j:log4j-api GHSA-qv9r-c865-cp47 vulnerable code not loaded
ch.qos.logback:logback-core GHSA-jhq6-gfmj-v8fx, GHSA-p47f-322f-whfh (not loaded); GHSA-qqpg-mvqg-649v (precondition unmet) see cell
io.micrometer:micrometer-core GHSA-w737-wx49-qj23 vulnerable code not loaded
io.netty:netty-codec-classes-quic GHSA-cmm3-54f8-px4j, GHSA-cq4q-cv5g-r8q5 vulnerable code not loaded (no QUIC)
io.netty:netty-codec-compression GHSA-558v-64gr-wgg4, GHSA-mj4r-2hfc-f8p6 vulnerable code not loaded
io.netty:netty-codec-dns GHSA-cm33-6792-r9fm, GHSA-mfg7-5gfp-c4w3 no attacker-controlled input
io.netty:netty-codec-http GHSA-4mp9-239f-g9hg, GHSA-6cqp-g7gg-8hr5, GHSA-6jqx-86gh-f27w, GHSA-8c42-7qj2-3j46, GHSA-gcjf-9mgh-3p7g, GHSA-jppx-w49h-x2qq, GHSA-mvh2-crg5-v77c (not loaded); GHSA-57rv-r2g8-2cj3, GHSA-f6hv-jmp6-3vwv (no attacker-controlled input) see cell
io.netty:netty-codec-http2 GHSA-563q-j3cm-6jxm, GHSA-5x3r-wrvg-rp6q, GHSA-93wv-jw9v-4972, GHSA-c2gf-v879-257j, GHSA-c69g-56f8-xwqj, GHSA-f6hv-jmp6-3vwv, GHSA-w9fj-cfpg-grvv unreachable from any entry point (HTTP/2 disabled)
io.netty:netty-codec-http3 GHSA-2c5c-chwr-9hqw, GHSA-4grm-h2qv-h6w6, GHSA-c2rx-5r8w-8xr2, GHSA-hpcc-26xq-25fv vulnerable code not loaded (no HTTP/3)
io.netty:netty-handler GHSA-3qp7-7mw8-wx86 (not loaded); GHSA-c653-97m9-rcg9, GHSA-x4gw-5cx5-pgmh (unreachable) see cell
io.netty:netty-handler-proxy GHSA-45q3-82m4-75jr vulnerable code not loaded
io.netty:netty-resolver-dns GHSA-5pvg-856g-cp85, GHSA-676x-f7gg-47vc, GHSA-xmv7-r254-6q78 no attacker-controlled input
io.netty:netty-transport-native-epoll GHSA-w573-9ffj-6ff9 vulnerable code not loaded
org.springframework.boot:spring-boot GHSA-8v8j-3hxp-93wr (not loaded); GHSA-wwpq-f5c3-7hvx (precondition unmet) see cell
org.springframework.boot:spring-boot-autoconfigure GHSA-ggg2-9786-hwc8 vulnerable code not loaded
org.springframework.boot:spring-boot-starter-actuator GHSA-8hfc-fq58-r658 (precondition unmet); GHSA-mgvc-8q2h-5pgc (not loaded) see cell
org.springframework:spring-core GHSA-659m-px2c-25wj no attacker-controlled input
org.springframework:spring-expression GHSA-9f52-rjqv-25qv, GHSA-r5w3-xv2f-j59q, GHSA-wxpp-56q6-5pcg no attacker-controlled input
org.springframework:spring-web GHSA-7m2p-62gw-p8qq no attacker-controlled input
org.springframework:spring-webflux GHSA-4hfh-6x8g-gwpp, GHSA-6p4f-wcwh-5vvm, GHSA-72pg-x5f8-j25j, GHSA-h3qp-gqrc-q736, GHSA-mq64-j8f9-9gcj, GHSA-wg35-8jpf-2xv3, GHSA-x23c-287f-qqv5 (precondition unmet); GHSA-4773-3jfm-qmx3, GHSA-5843-p793-ghmm, GHSA-6hcq-hmm3-jj3c, GHSA-83f7-v6px-pp3h, GHSA-cjpg-rgq5-fr37 (unreachable) see cell

DEFER: why these alerts are safely deferrable

This section is the evidence that each deferral was earned. The deferrals below were produced by the same analysis, to the same evidentiary standard, as the findings scheduled above: one process, one quality bar, different outcomes on different evidence. Reading the vendored dependency sources under vendor/ and the eight modules' own code is what separates them.

All 580 deferred findings share one threat fact: none is listed in KEV, and every one that has an EPSS score carries a percentile below the p99 top-1% line that the rubric treats as imminent threat. They also share one asset fact: all sit on internal, tier_2, production services, or on the two dev-scoped dependencies noted in group 1. What differs is the reachability evidence, and the five groups below are organized by it. The group counts sum to 580.

Group 1: the vulnerable code is not delivered or not loaded (162 findings)

Residual Low, 20/100 (inherent High 80; 60 points retired) on every member.

The strongest form of deferral evidence: the code carrying the flaw is never on the running classpath, or is on the classpath but never constructed. Members:

  • Netty optional protocol stacks on api-gateway, admin-server, and genai-service: netty-codec-classes-quic (2 advisories), netty-codec-http3 (4), netty-codec-compression (2), netty-handler-proxy (1), netty-transport-native-epoll (1), plus the WebSocket, CORS, SPDY, and Bzip2/LZ4 paths inside netty-codec-http (7 advisories) and netty-handler GHSA-3qp7-7mw8-wx86. None of these protocols or handlers is enabled anywhere in the project: no QUIC, no HTTP/3, no WebSockets, no proxy handler, and no compression codec on the wire.
  • The entire Tomcat surface on genai-service: all 13 tomcat-embed-core advisories. The genai service sets spring.main.web-application-type: reactive, so Tomcat is present on the classpath as a transitive artifact and is never constructed. This is the clearest case in the set: the vulnerable server is shipped and never started.
  • Tomcat components no module configures, on customers-service, vets-service, visits-service, config-server, and discovery-server: WebDAV, the AJP connector, DIGEST authentication, LockOutRealm, JsonAccessLogValve, clustering, Tomcat Native and OCSP, and the WebSocket client (9 advisories per module).
  • Logging internals: log4j-api GHSA-qv9r-c865-cp47 across all eight modules, and logback-core GHSA-jhq6-gfmj-v8fx and GHSA-p47f-322f-whfh across all eight. The affected appenders and lookups are not configured in any module.
  • BouncyCastle GHSA-574f-3g2m-x479 and GHSA-c3fc-8qff-9hwx across all eight modules: the affected algorithms are not invoked; BouncyCastle arrives transitively and no module registers it as a JCA provider.
  • Micrometer GHSA-w737-wx49-qj23 across seven modules, spring-boot GHSA-8v8j-3hxp-93wr and spring-boot-autoconfigure GHSA-ggg2-9786-hwc8 across all eight, spring-boot-starter-actuator GHSA-mgvc-8q2h-5pgc across seven, and spring-webmvc GHSA-957g-f97v-vppc across six: each names a component none of these applications configures.
  • spring-boot-devtools GHSA-56v8-86gj-66jp on api-gateway: declared <optional>true</optional> and excluded from the repackaged jar by the Spring Boot Maven plugin, so it exists at development time only and never ships in the container image.

What would change these verdicts: enabling one of the named protocols or components. Turning on HTTP/3 or QUIC at the gateway, switching genai-service back to a servlet stack, configuring an AJP connector or a Tomcat cluster, or registering BouncyCastle as a JCA provider each makes the corresponding code loaded, at which point reachability must be re-analyzed rather than assumed.

Group 2: the vulnerable code is unreachable from any entry point (155 findings)

Residual Low, 20/100 (inherent High 80; 60 points retired) on every member.

The code is loaded, and no path reaches it from anything an attacker can call. Members:

  • The whole HTTP/2 family: netty-codec-http2 (7 advisories on api-gateway, admin-server, and genai-service), httpcore5-h2 GHSA-v3jc-474w-2wm6 (all eight modules), netty-handler GHSA-c653-97m9-rcg9 and GHSA-x4gw-5cx5-pgmh, and Tomcat's HTTP/2 header handling GHSA-r29c-68gh-xp6x (six modules). HTTP/2 is off across the deployment. The risk-context file states this for the gateway, and no service enables server.http2.enabled.
  • Jackson polymorphic typing and InetSocketAddress deserialization: jackson-databind GHSA-hgj6-7826-r7m5, GHSA-j3rv-43j4-c7qm, and GHSA-rmj7-2vxq-3g9f in both the Jackson 2 and Jackson 3 artifacts, across every module that carries them. No module enables default typing, and no deserialized type contains an InetSocketAddress.
  • Jackson async and DataInput parser paths on the servlet services: jackson-core GHSA-72hv-8253-57qq and GHSA-r7wm-3cxj-wff9 on customers-service, vets-service, visits-service, config-server, and discovery-server, and GHSA-6v53-7c9g-w56r everywhere. The non-blocking parser is a WebFlux path, and these services run Tomcat with the blocking parser; no module reads JSON from a DataInput.
  • Guava GHSA-5mg8-w23w-74h3, GHSA-7g45-4rm6-3mm3, and GHSA-mvr2-9pj6-7w5j across six modules: the affected AtomicDoubleArray deserialization, temp-file creation, and MediaType parsing entry points are not called by any application code, and Guava arrives only transitively.
  • Spring WebFlux and Spring MVC handler paths that no module maps: GHSA-4773-3jfm-qmx3, GHSA-5843-p793-ghmm, GHSA-6hcq-hmm3-jj3c, GHSA-83f7-v6px-pp3h, GHSA-3chg-m5w7-qfv5, and the non-servlet cjpg locations. Each requires a mapping, view resolver, or handler configuration that no module declares.
  • Spring Data Commons GHSA-5vpf-xvv7-c8vh, GHSA-88fw-v6x4-3f58, and GHSA-9fw2-h3hf-293r on customers-service, vets-service, visits-service, and genai-service: the affected query-derivation and projection paths are not reachable from the repository interfaces these services declare.

What would change these verdicts: enabling HTTP/2 on any listener, enabling Jackson default typing, moving a servlet service to the reactive stack, or adding a handler mapping that reaches one of the named WebFlux or MVC paths. Any of those turns "unreachable" into a reachability question that must be re-traced.

Group 3: the advisory's own triggering precondition is not met (89 findings)

Residual Low, 20/100 (inherent High 80; 60 points retired) on every member.

The code is loaded and reachable, and the specific configuration the advisory requires is absent. These are the deferrals that most reward reading the advisory rather than the CVSS vector. Members:

  • The Spring static-resource family: GHSA-mq64-j8f9-9gcj, GHSA-72pg-x5f8-j25j, GHSA-x23c-287f-qqv5, GHSA-wg35-8jpf-2xv3, and GHSA-6p4f-wcwh-5vvm, in both spring-webmvc and spring-webflux, across every module that carries them. Each requires the Spring resource chain, a version strategy, encoded-resource resolution, or a resource cache. vendor/spring-boot-autoconfigure-4.0.1/.../WebProperties.java shows Chain.enabled as a @Nullable Boolean with a null default and Strategy.Content.enabled, Strategy.Fixed.enabled, and compressed all defaulting to false, and no module sets spring.web.resources.chain. GHSA-6p4f-wcwh-5vvm additionally requires a Windows host serving file-system resources; these services run Linux eclipse-temurin:17 containers serving classpath resources.
  • Spring MVC and WebFlux GHSA-h3qp-gqrc-q736: requires a /** mapping whose view name is left unspecified. The gateway's only catch-all is RouterFunctions.resources("/**", new ClassPathResource("static/")), which is a resource handler rather than a view mapping, and no other module declares one.
  • Spring WebFlux GHSA-4hfh-6x8g-gwpp: requires an authentication step that rotates the WebSession. Spring Security is absent from every module, so no authentication step exists to rotate anything.
  • Spring Boot GHSA-wwpq-f5c3-7hvx: requires server.servlet.session.persistent=true, which no module sets, so no session state is written to the predictable temp directory the advisory describes.
  • Spring Boot Actuator GHSA-8hfc-fq58-r658: requires an authorization rule protecting Actuator endpoints that the flaw can bypass. No such rule exists, because Spring Security is absent. See the configuration note in Next Steps: the absence that makes this advisory inapplicable is itself worth a look.
  • Jackson 3 annotation-gated defects on customers-service and visits-service: GHSA-3pjw-73gf-8qr5, GHSA-5gvw-p9qm-jgwh, GHSA-5hh8-q8hv-fr38, GHSA-9fxm-vc8v-hj55, and GHSA-rcqc-6cw3-h962. These are the two services where anonymous JSON does reach jackson-databind, so the annotation precondition carries the deferral rather than the input question. Each requires a specific annotation combination on a deserialized type: @JsonIgnore on a record property with a naming strategy, @JsonView on an @JsonUnwrapped container, @JsonView on a setterless creator property, a renamed @JsonIgnored setter, or @JsonView on an unwrapped creator parameter. None of the deserialized types in either service uses @JsonView or @JsonUnwrapped at all.
  • Logback GHSA-qqpg-mvqg-649v across all eight modules: requires write access to a logback configuration file. The configuration ships inside the container image and no untrusted actor can write it.
  • Tomcat GHSA-5m62-pw8w-7w9f on five modules: requires two or more security constraints declaring an HTTP method constraint on the same extension pattern. No module declares any security constraint.
  • Spring Data Commons GHSA-5m4m-73w9-8433 on four modules: requires a controller method annotated @ProjectedPayload with Spring Data Web Support. No module declares one.

What would change these verdicts: setting spring.web.resources.chain.enabled=true or a version strategy; adding Spring Security and with it an authentication step and Actuator authorization rules; adding @JsonView or @JsonUnwrapped to a deserialized type; setting server.servlet.session.persistent=true; or declaring servlet security constraints. Each of these is a normal, desirable change that would flip a group member, which is exactly why the precondition is recorded per finding rather than assumed stable. One dependency is external: several static-resource deferrals rest on spring.web.resources.chain being unset, and the effective configuration is assembled by config-server from the spring-petclinic-microservices-config repository at commit 323993c. A change in that repository can flip these without any change in this one.

Group 4: the vulnerable code is reached only with first-party input (169 findings)

Residual Low, 20/100 (inherent High 80; 60 points retired) on every member.

The code runs, and the values that reach it come from the application, the operators, or the internal service mesh, never from the one untrusted actor the trust model names. Members:

  • The Netty and Apache HTTP client stacks: httpclient GHSA-7r82-7xv7-xcpj, httpclient5 GHSA-hjcp-jmpx-g3qm, httpcore5 GHSA-hf6x-8p5f-cgmf, netty-codec-dns (2 advisories), and netty-resolver-dns (3 advisories). These parse responses from internal backends and from the DNS resolver, both of which are inside the trust boundary. The gateway's proxy client installs no response decompressor, and the owner-aggregation WebClient that does install HttpContentDecompressor reads only from internal backends that never compress.
  • Tomcat chunk-extension handling GHSA-563x-q5rq-57qp on the five servlet services: the gateway normalizes HTTP/1.1 framing on the way to backends and drops chunk extensions, so only body bytes pass through verbatim. The backends never see an attacker-shaped chunk extension.
  • Netty HTTP/1.1 findings on admin-server and genai-service that are traced positives on the gateway: GHSA-38f8-5428-x5cv, GHSA-m4cv-j2px-7723, GHSA-pwqr-wmgm-9rr8, GHSA-xxqh-mfjm-7mv9, GHSA-hvcg-qmg6-jm4c, GHSA-v8h7-rr48-vmmv, GHSA-f6hv-jmp6-3vwv, and GHSA-57rv-r2g8-2cj3. The gateway routes nothing to admin-server or genai-service's Netty listener from the internet, and the risk-context file states the gateway re-encodes framing, so these two services receive only gateway-generated HTTP/1.1.
  • Spring Expression GHSA-9f52-rjqv-25qv, GHSA-r5w3-xv2f-j59q, and GHSA-wxpp-56q6-5pcg across all eight modules, and spring-core GHSA-659m-px2c-25wj: no module evaluates a SpEL expression built from request input.
  • Spring Web GHSA-7m2p-62gw-p8qq across all eight modules, commons-lang GHSA-j288-q9x7-2f5v and commons-configuration GHSA-pvp8-3xj6-8c6x across seven: reached only with configuration and internally generated values.
  • Thymeleaf and thymeleaf-spring6 (3 advisories each) on admin-server: templates render operator-facing data from the Spring Boot Admin server, not caller-supplied expressions.
  • The Jackson 3 annotation-gated defects on the six modules where anonymous JSON does not reach databind, and the jackson-databind GHSA-3pjw-73gf-8qr5 and GHSA-5jmj-h7xm-6q6v pair where the same reasoning applies.
  • Micrometer GHSA-g3pr-3p32-fp23 on config-server, discovery-server, and admin-server, and spring-webmvc GHSA-cjpg-rgq5-fr37 on config-server and discovery-server: the gateway routes nothing to the platform services, so their metric tags and request bodies come only from operators and from internal callers.
  • spring-cloud-config-server GHSA-2mh5-3cw6-hrrq, GHSA-3qwq-q9vm-5j42, GHSA-6g23-24mc-hx6x, GHSA-86wq-234q-r6wg, and GHSA-j6hh-h3cf-c2hf on config-server: the git backend reads the upstream configuration repository, which the trust model lists as a trusted actor, and the gateway routes nothing to config-server.
  • assertj-core GHSA-rqfh-9r24-8c9r on seven modules: declared <scope>test</scope> in every POM that names it. It is scored against a dev lifecycle context, following the code path rather than the module, and it never runs in production.

What would change these verdicts: routing internet traffic directly to admin-server, genai-service, config-server, or discovery-server, which the gateway does not do today; removing the gateway's HTTP/1.1 framing normalization; making an internal backend able to return attacker-influenced compressed or chunked responses; or building a SpEL expression or a Thymeleaf fragment name from request input.

Group 5: reachability honestly undetermined, threat confidently absent (5 findings)

Residual Moderate, 50/100 (inherent High 80; 30 points retired) on every member.

tomcat-embed-core GHSA-8mc5-53m5-3qj2 (CVE-2026-32990) on customers-service, vets-service, visits-service, config-server, and discovery-server. The advisory describes an incomplete fix for CVE-2025-66614 and names no vulnerable symbol and no triggering precondition, so there is no call site to enumerate and no configuration to check. That is a legitimate answer about the advisory, not a gap in the work, and it is recorded as undetermined rather than guessed in either direction. These five carry a Moderate residual rather than Low precisely because the analysis declined to claim unreachability.

They are deferred on the threat side: CVE-2026-32990 is not listed in KEV, and its EPSS percentile is 22.99 with a raw score of 0.00307, well below the p99 top-1% line and below the p90 mark the rubric uses for confident absence.

What would change these verdicts: an updated advisory that names the affected component or a trigger condition, which would let reachability be determined; or threat evidence appearing. Because Impact is present on these tier_2 production assets, a top-1% EPSS score would move the base bucket to SCHEDULE, and a KEV listing would additionally activate the kev_emergency floor.

The boundary of the deferral claim

Two kinds of deferred finding deserve monitoring rather than filing away.

EPSS gray-zone members, p90 to p99. Thirteen deferred alerts sit above p90 and below the p99 top-1% line: com.google.guava:guava GHSA-mvr2-9pj6-7w5j (CVE-2018-10237) at percentile 91.81, raw score 0.05119, on six modules; and org.apache.httpcomponents:httpclient GHSA-7r82-7xv7-xcpj (CVE-2020-13956) at percentile 94.92, raw score 0.09032, on seven modules. Both are old, widely known, and unreachable here. EPSS is retrained daily, so a move across p99 on either one would make Threat present. Because Impact is present on these assets, that alone moves the base bucket from DEFER to SCHEDULE, and a KEV listing would activate the kev_emergency floor besides.

Threat-unknown members awaiting records. Twenty-three deferred alerts carry no KEV entry and no EPSS score, because their advisories have no CVE alias: jackson-core GHSA-r7wm-3cxj-wff9 in the Jackson 2 artifact (7 modules) and the Jackson 3 artifact (8 modules), and tools.jackson.core:jackson-core GHSA-2m67-wjpj-xhg9 (8 modules, of which the customers-service and visits-service locations are the two REVIEW findings above, not deferrals). Their Threat factor is unknown rather than absent, and their residual scores carry medium confidence for that reason. A CVE assignment and a first EPSS score would resolve the factor in either direction. These verdicts can change; that is why they are named here.

Next Steps

Investigate before deciding. Two findings: tools.jackson.core:jackson-core GHSA-2m67-wjpj-xhg9 on customers-service and visits-service. The missing evidence is threat: the advisory has no CVE alias, so no KEV record and no EPSS score exist. Reachability is determined and positive on both. Do not dismiss these two. Either wait for a CVE assignment and re-score, or upgrade tools.jackson.core:jackson-core past 3.0.3 to the fixed release named in the advisory; upgrading may cost less than investigating, and whether it does depends on your code and your release schedule.

Schedule by policy window. Eighteen findings have a traced path from an anonymous internet caller to vulnerable code and sit in the policy's 60-day Moderate window: the eight Netty findings on api-gateway, micrometer-core GHSA-g3pr-3p32-fp23 on five services, spring-webmvc GHSA-cjpg-rgq5-fr37 on three services, and spring-ai GHSA-q62f-h9x2-gcqc on genai-service. Three changes clear all eighteen: bump netty.version in the parent POM, bump micrometer.version or cap HTTP metric tag cardinality, and bump spring-framework.version or set spring.servlet.multipart.resolve-lazily=true. The genai chat-memory leak is fixed in your own code by passing a per-user conversation id to the memory advisor, with no dependency change at all; that one is worth doing first, because it is the only finding in this set with a data-confidentiality consequence.

The remaining 91 SCHEDULE findings are unreachable on the gateway and carry the public_asset_floor. Fold them into the project's normal dependency-upgrade cadence in the 180-day Low window. No individual investigation is warranted.

No action, annotate the alert. 580 findings. Record the deferral rationale on each alert rather than closing it silently; the ready-to-run commands are in the alert-dismissal appendix. Re-score on the next dependency change or on a KEV or EPSS movement in the thirteen gray-zone and twenty-three threat-unknown alerts named above.

One configuration finding, outside the alert set. The analysis surfaced a standing exposure that no dependency alert reports: management.endpoints.web.exposure.include: '*' on spring-petclinic-api-gateway, a public_unauth service with no Spring Security on the classpath. Every Actuator endpoint, including /actuator/env and /actuator/heapdump, is served unauthenticated to the internet. This is what makes Actuator advisory GHSA-8hfc-fq58-r658 inapplicable: there is no authorization rule for the flaw to bypass. Treat it as its own item, not as part of this triage.

Appendix: Triage metadata

This appendix is for the reviewer auditing how these verdicts were produced: who and what produced them, from what inputs, with what caveats.

Project: spring-petclinic-microservices
Date: 2026-09-03
Rubric: k9 risk scoring rubric 2026.08.24-v27, workflow 2026.09.03-v34
Scored and reported by: claude-opus-5
Risk context: 2026-09-02+3858f9c630cf989bb6809a86edf47c2be78dc9f1
SLA: SafeCo Vulnerability Management Policy ISP-07 v1.0, calendar days
Findings scored: 691 alerts (691 context-specific verdicts)

  • Count verification: the alert list supplied with this run declared 691 open alerts, and the JSON array contained 691 records. Scoring ran in 35 batches; batch_stats.alerts_total summed to 691 across those batches, and batch_stats.findings_total also summed to 691 with bindings_per_alert equal to 1 in every batch. Each alert names a single execution context in its finding_key suffix, so each produced exactly one verdict. The counts reconcile with no shortfall and no grouping.
  • Quality flags: none. batch_stats.quality_flags was empty in all 35 batches, default_context_fraction was 0 in all 35, and distinct_basis_tokens was 1 throughout, meaning every finding was bound to a stated execution context from the risk-context file and every reachability call cited the same basis-procedure token issued to this session.
  • Unbound alerts: none. batch_stats.findings_without_context_binding was empty in all 35 batches. Every verdict names one of the three execution contexts declared in .k9security/risk-context.yaml: runtime-gateway (102 alerts), runtime-services (431 alerts across customers, vets, visits, and genai), and runtime-platform (158 alerts across config, discovery, and admin).
  • Basis-procedure token: 2026.08.24-v5-9a632c63-4a7cb06f, issued to this session by k9://rubric/basis-procedure version 2026.08.24-v5 and cited on all 691 reachability calls.
  • Reachability basis histogram, all 691: no attacker-controlled input 196, vulnerable code not loaded 189, unreachable from entry point 182, advisory precondition unmet 99, traced call graph 20, undetermined 5. The undetermined share is 0.7%, below the rubric's flag threshold.
  • Dev-lifecycle scoring: eight alerts were scored against a dev lifecycle asset context rather than production, following the code path rather than the module: assertj-core GHSA-rqfh-9r24-8c9r on seven modules, which every POM declaring it marks <scope>test</scope>, and spring-boot-devtools GHSA-56v8-86gj-66jp on api-gateway, which is declared <optional>true</optional> and excluded from the repackaged jar.
  • External configuration dependency: several advisory_precondition_unmet deferrals rest on properties this repository does not set, and the effective configuration is assembled by config-server from the spring-petclinic-microservices-config repository at commit 323993c. The analysis read this repository and the risk-context file; it did not read that external repository. A change there can flip those deferrals without any change here.
  • Policy directives: the supplied SafeCo ISP-07 v1.0 policy was used only for its risk-to-SLA mapping, its clock rule, its day basis, and its own name and version. It changed no verdict, bucket, reachability call, or NIST value. Its exception clause, that exceptions require CISO approval with a compensating-control justification and an expiry not exceeding 12 months, is recorded here as a reported claim about your process rather than an instruction this analysis followed.
  • SLA clock could not be started: ISP-07 dates its clock from the day an alert was opened in the tracking tool. The supplied alert records carry finding_key, vuln_id, cve_id, package, ecosystem, installed_version, manifest_path, and summary, and no open or created date. Every SLA cell in this report therefore renders ? with the policy window that applies. No finding could be shown as past due or as within its window; supplying alert open dates resolves every expiry date automatically.

Appendix: Risk scores (NIST SP 800-30)

This appendix is for the reviewer and the engineer reconciling policy: every finding's scores, drivers, and deadlines.

Three terms, in plain language:

  • Inherent risk: how bad this flaw would be if you assumed the worst, with attackers actively exploiting it and your code running the vulnerable path.
  • Residual risk: what risk remains after checking the two things that usually are not true, whether attackers are really exploiting it and whether your code can even reach the vulnerability. This is the risk you are carrying now.
  • Retired risk: the risk the analysis ruled out, measured as how far the number fell from inherent to residual.

The residual value is the k9 assessment and is the risk score to report. The inherent value is a standard NIST assessment with none of that credit, an assume-the-worst baseline on the same asset.

The reachability and exploitability analysis retired 40,650 points (73.5% of the 55,280 inherent points across 691 findings), safely deferred 580 of 691 findings, and moved 666 findings from a High inherent band to a Low residual band. All three numbers matter together: retired is impact-gated, so on a lower-impact asset a perfect deferral can retire nothing, and the deferral count rather than the point total would carry the value.

Read every value below straight from the verdicts. Retired values take exactly three levels in this scan: 60 on the 666 findings with Low residual, 30 on the 23 with Moderate residual, and 0 on the 2 REVIEW findings.

The NIST score is inherent-risk context, not an action signal. The verdict is the action signal; the scores are context. That is why 91 gateway findings show a Low residual band alongside a SCHEDULE verdict: the public_asset_floor sets the bucket on a public asset, while the graded NIST projection reads the underlying reachability evidence, which is negative. Anchor priority on the verdict and use the residual as context or a tiebreaker.

SLA Expiry renders ? on every row: ISP-07's clock starts at the alert open date, and the supplied alert records contain none. The policy window that applies is given in parentheses, keyed on the residual band per ISP-07 (Very High 96-100 → 7 days; High 80-95 → 30 days; Moderate 21-79 → 60 days; Low 1-20 → 180 days; Very Low 0 → 365 days).

Rows are ordered highest residual composite first, and identical vuln_ids with the same verdict and evidence are grouped, with locations named.

Residual High, 80/100

Vuln ID Verdict Driver Residual risk Residual Inherent Retired SLA Expiry
GHSA-2m67-wjpj-xhg9 (customers, visits) REVIEW threat unknown; reachable (traced) High 80 (low conf) 80 0 ? (30-day window)

Residual Moderate, 50/100

Vuln ID Verdict Driver Residual risk Residual Inherent Retired SLA Expiry
GHSA-38f8-5428-x5cv (gateway) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-m4cv-j2px-7723 (gateway) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-pwqr-wmgm-9rr8 (gateway) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-xxqh-mfjm-7mv9 (gateway) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-hvcg-qmg6-jm4c (gateway) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-v8h7-rr48-vmmv (gateway) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-q4f6-jm68-57ww (gateway) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-rwm7-x88c-3g2p (gateway) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-g3pr-3p32-fp23 (gateway, customers, vets, visits, genai) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-cjpg-rgq5-fr37 (customers, vets, visits) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-q62f-h9x2-gcqc (genai, 2 packages) SCHEDULE reachable (traced) Moderate 50 80 30 ? (60-day window)
GHSA-8mc5-53m5-3qj2 (customers, vets, visits, config, discovery) DEFER undetermined; threat absent Moderate 50 80 30 ? (60-day window)

Twenty-three findings, matching the eighteen traced SCHEDULE locations and the five undetermined DEFER locations.

Residual Low, 20/100 — SCHEDULE on the public gateway (91 findings)

All 91 share Driver public_asset_floor, Residual Low 20, Inherent High 80, Retired 60, and SLA ? (180-day window). Every one is on spring-petclinic-api-gateway.

Vuln ID Reachability driver detail
GHSA-574f-3g2m-x479, GHSA-c3fc-8qff-9hwx code not loaded (bcprov)
GHSA-pvp8-3xj6-8c6x, GHSA-j288-q9x7-2f5v no attacker-controlled input
GHSA-5mg8-w23w-74h3, GHSA-7g45-4rm6-3mm3, GHSA-mvr2-9pj6-7w5j unreachable from entrypoint (guava)
GHSA-7r82-7xv7-xcpj, GHSA-hjcp-jmpx-g3qm, GHSA-hf6x-8p5f-cgmf no attacker-controlled input (HTTP clients)
GHSA-v3jc-474w-2wm6 unreachable from entrypoint (HTTP/2 off)
GHSA-72hv-8253-57qq, GHSA-r7wm-3cxj-wff9 (jackson2-core) unreachable from entrypoint
GHSA-2m67-wjpj-xhg9, GHSA-72hv-8253-57qq, GHSA-r7wm-3cxj-wff9 (tools-core) no attacker-controlled input
GHSA-6v53-7c9g-w56r unreachable from entrypoint
GHSA-3pjw-73gf-8qr5, GHSA-5jmj-h7xm-6q6v (jackson2-databind) no attacker-controlled input
GHSA-hgj6-7826-r7m5, GHSA-j3rv-43j4-c7qm, GHSA-rmj7-2vxq-3g9f (jackson2-databind) unreachable from entrypoint
GHSA-3pjw-73gf-8qr5, GHSA-5gvw-p9qm-jgwh, GHSA-5hh8-q8hv-fr38, GHSA-9fxm-vc8v-hj55, GHSA-rcqc-6cw3-h962 (tools-databind) no attacker-controlled input
GHSA-hgj6-7826-r7m5, GHSA-j3rv-43j4-c7qm, GHSA-rmj7-2vxq-3g9f (tools-databind) unreachable from entrypoint
GHSA-qv9r-c865-cp47, GHSA-jhq6-gfmj-v8fx, GHSA-p47f-322f-whfh code not loaded (logging)
GHSA-qqpg-mvqg-649v advisory precondition unmet (config not writable)
GHSA-w737-wx49-qj23 code not loaded (micrometer)
GHSA-cmm3-54f8-px4j, GHSA-cq4q-cv5g-r8q5, GHSA-558v-64gr-wgg4, GHSA-mj4r-2hfc-f8p6, GHSA-2c5c-chwr-9hqw, GHSA-4grm-h2qv-h6w6, GHSA-c2rx-5r8w-8xr2, GHSA-hpcc-26xq-25fv, GHSA-45q3-82m4-75jr, GHSA-w573-9ffj-6ff9, GHSA-3qp7-7mw8-wx86 code not loaded (netty optional stacks)
GHSA-cm33-6792-r9fm, GHSA-mfg7-5gfp-c4w3, GHSA-5pvg-856g-cp85, GHSA-676x-f7gg-47vc, GHSA-xmv7-r254-6q78 no attacker-controlled input (DNS)
GHSA-4mp9-239f-g9hg, GHSA-6cqp-g7gg-8hr5, GHSA-6jqx-86gh-f27w, GHSA-8c42-7qj2-3j46, GHSA-gcjf-9mgh-3p7g, GHSA-jppx-w49h-x2qq, GHSA-mvh2-crg5-v77c code not loaded (netty-codec-http optional handlers)
GHSA-57rv-r2g8-2cj3, GHSA-f6hv-jmp6-3vwv (netty-codec-http) no attacker-controlled input
GHSA-563q-j3cm-6jxm, GHSA-5x3r-wrvg-rp6q, GHSA-93wv-jw9v-4972, GHSA-c2gf-v879-257j, GHSA-c69g-56f8-xwqj, GHSA-f6hv-jmp6-3vwv, GHSA-w9fj-cfpg-grvv (netty-codec-http2) unreachable from entrypoint (HTTP/2 off)
GHSA-c653-97m9-rcg9, GHSA-x4gw-5cx5-pgmh unreachable from entrypoint
GHSA-8v8j-3hxp-93wr, GHSA-ggg2-9786-hwc8, GHSA-mgvc-8q2h-5pgc code not loaded (Boot / actuator)
GHSA-wwpq-f5c3-7hvx, GHSA-8hfc-fq58-r658 advisory precondition unmet
GHSA-659m-px2c-25wj, GHSA-9f52-rjqv-25qv, GHSA-r5w3-xv2f-j59q, GHSA-wxpp-56q6-5pcg, GHSA-7m2p-62gw-p8qq no attacker-controlled input
GHSA-4hfh-6x8g-gwpp, GHSA-6p4f-wcwh-5vvm, GHSA-72pg-x5f8-j25j, GHSA-h3qp-gqrc-q736, GHSA-mq64-j8f9-9gcj, GHSA-wg35-8jpf-2xv3, GHSA-x23c-287f-qqv5 (webflux) advisory precondition unmet
GHSA-4773-3jfm-qmx3, GHSA-5843-p793-ghmm, GHSA-6hcq-hmm3-jj3c, GHSA-83f7-v6px-pp3h, GHSA-cjpg-rgq5-fr37 (webflux) unreachable from entrypoint

Residual Low, 20/100 — DEFER (575 findings)

All 575 share Residual Low 20, Inherent High 80, Retired 60, and SLA ? (180-day window). Verdict DEFER throughout. Drivers are threat+exposure absent, with the reachability basis named per row. Module abbreviations: gw api-gateway, cu customers-service, ve vets-service, vi visits-service, cf config-server, di discovery-server, ad admin-server, ge genai-service.

Vuln ID Package Driver / basis Locations Count
GHSA-rqfh-9r24-8c9r org.assertj:assertj-core no attacker-controlled input; test scope, dev lifecycle gw, cu, ve, vi, cf, di, ge 7
GHSA-56v8-86gj-66jp org.springframework.boot:spring-boot-devtools code not loaded; optional, excluded from jar gw 1
GHSA-574f-3g2m-x479 org.bouncycastle:bcprov-jdk18on code not loaded cu, ve, vi, cf, di, ad, ge 7
GHSA-c3fc-8qff-9hwx org.bouncycastle:bcprov-jdk18on code not loaded cu, ve, vi, cf, di, ad, ge 7
GHSA-pvp8-3xj6-8c6x commons-configuration:commons-configuration no attacker-controlled input cu, ve, vi, di, ad, ge 6
GHSA-j288-q9x7-2f5v commons-lang:commons-lang no attacker-controlled input cu, ve, vi, di, ad, ge 6
GHSA-5mg8-w23w-74h3 com.google.guava:guava unreachable from entrypoint cu, ve, vi, ad, ge 5
GHSA-7g45-4rm6-3mm3 com.google.guava:guava unreachable from entrypoint cu, ve, vi, ad, ge 5
GHSA-mvr2-9pj6-7w5j com.google.guava:guava unreachable from entrypoint; EPSS gray zone p91.81 cu, ve, vi, ad, ge 5
GHSA-7r82-7xv7-xcpj org.apache.httpcomponents:httpclient no attacker-controlled input; EPSS gray zone p94.92 cu, ve, vi, di, ad, ge 6
GHSA-hjcp-jmpx-g3qm org.apache.httpcomponents.client5:httpclient5 no attacker-controlled input cu, ve, vi, cf, di, ad, ge 7
GHSA-hf6x-8p5f-cgmf org.apache.httpcomponents.core5:httpcore5 no attacker-controlled input cu, ve, vi, cf, di, ad, ge 7
GHSA-v3jc-474w-2wm6 org.apache.httpcomponents.core5:httpcore5-h2 unreachable from entrypoint (HTTP/2 off) cu, ve, vi, cf, di, ad, ge 7
GHSA-72hv-8253-57qq com.fasterxml.jackson.core:jackson-core unreachable from entrypoint cu, ve, vi, di, ad, ge 6
GHSA-r7wm-3cxj-wff9 com.fasterxml.jackson.core:jackson-core unreachable from entrypoint; threat unknown, medium confidence cu, ve, vi, di, ad, ge 6
GHSA-2m67-wjpj-xhg9 tools.jackson.core:jackson-core no attacker-controlled input; threat unknown, medium confidence ve, cf, di, ad, ge 5
GHSA-6v53-7c9g-w56r tools.jackson.core:jackson-core unreachable from entrypoint cu, ve, vi, cf, di, ad, ge 7
GHSA-72hv-8253-57qq tools.jackson.core:jackson-core unreachable from entrypoint cu, ve, vi, cf, di 5
GHSA-72hv-8253-57qq tools.jackson.core:jackson-core no attacker-controlled input ad, ge 2
GHSA-r7wm-3cxj-wff9 tools.jackson.core:jackson-core unreachable from entrypoint; threat unknown, medium confidence cu, ve, vi, cf, di 5
GHSA-r7wm-3cxj-wff9 tools.jackson.core:jackson-core no attacker-controlled input; threat unknown, medium confidence ad, ge 2
GHSA-3pjw-73gf-8qr5 com.fasterxml.jackson.core:jackson-databind no attacker-controlled input cu, ve, vi, di, ad, ge 6
GHSA-5jmj-h7xm-6q6v com.fasterxml.jackson.core:jackson-databind no attacker-controlled input cu, ve, vi, di, ad, ge 6
GHSA-hgj6-7826-r7m5 com.fasterxml.jackson.core:jackson-databind unreachable from entrypoint cu, ve, vi, di, ad, ge 6
GHSA-j3rv-43j4-c7qm com.fasterxml.jackson.core:jackson-databind unreachable from entrypoint cu, ve, vi, di, ad, ge 6
GHSA-rmj7-2vxq-3g9f com.fasterxml.jackson.core:jackson-databind unreachable from entrypoint cu, ve, vi, di, ad, ge 6
GHSA-3pjw-73gf-8qr5 tools.jackson.core:jackson-databind advisory precondition unmet (@JsonIgnore record property + naming strategy) cu, vi 2
GHSA-5gvw-p9qm-jgwh tools.jackson.core:jackson-databind advisory precondition unmet (@JsonView on @JsonUnwrapped) cu, vi 2
GHSA-5hh8-q8hv-fr38 tools.jackson.core:jackson-databind advisory precondition unmet (@JsonView setterless creator) cu, vi 2
GHSA-9fxm-vc8v-hj55 tools.jackson.core:jackson-databind advisory precondition unmet (renamed @JsonIgnored setter) cu, vi 2
GHSA-rcqc-6cw3-h962 tools.jackson.core:jackson-databind advisory precondition unmet (@JsonView unwrapped creator param) cu, vi 2
GHSA-3pjw-73gf-8qr5 tools.jackson.core:jackson-databind no attacker-controlled input ve, cf, di, ad, ge 5
GHSA-5gvw-p9qm-jgwh tools.jackson.core:jackson-databind no attacker-controlled input ve, cf, di, ad, ge 5
GHSA-5hh8-q8hv-fr38 tools.jackson.core:jackson-databind no attacker-controlled input ve, cf, di, ad, ge 5
GHSA-9fxm-vc8v-hj55 tools.jackson.core:jackson-databind no attacker-controlled input ve, cf, di, ad, ge 5
GHSA-rcqc-6cw3-h962 tools.jackson.core:jackson-databind no attacker-controlled input ve, cf, di, ad, ge 5
GHSA-hgj6-7826-r7m5 tools.jackson.core:jackson-databind unreachable from entrypoint cu, ve, vi, cf, di, ad, ge 7
GHSA-j3rv-43j4-c7qm tools.jackson.core:jackson-databind unreachable from entrypoint cu, ve, vi, cf, di, ad, ge 7
GHSA-rmj7-2vxq-3g9f tools.jackson.core:jackson-databind unreachable from entrypoint cu, ve, vi, cf, di, ad, ge 7
GHSA-qv9r-c865-cp47 org.apache.logging.log4j:log4j-api code not loaded cu, ve, vi, cf, di, ad, ge 7
GHSA-jhq6-gfmj-v8fx ch.qos.logback:logback-core code not loaded cu, ve, vi, cf, di, ad, ge 7
GHSA-p47f-322f-whfh ch.qos.logback:logback-core code not loaded cu, ve, vi, cf, di, ad, ge 7
GHSA-qqpg-mvqg-649v ch.qos.logback:logback-core advisory precondition unmet (config file not writable) cu, ve, vi, cf, di, ad, ge 7
GHSA-g3pr-3p32-fp23 io.micrometer:micrometer-core no attacker-controlled input di, ad 2
GHSA-w737-wx49-qj23 io.micrometer:micrometer-core code not loaded cu, ve, vi, di, ad, ge 6
GHSA-cmm3-54f8-px4j, GHSA-cq4q-cv5g-r8q5 io.netty:netty-codec-classes-quic code not loaded (no QUIC) ad, ge 4
GHSA-558v-64gr-wgg4, GHSA-mj4r-2hfc-f8p6 io.netty:netty-codec-compression code not loaded ad, ge 4
GHSA-cm33-6792-r9fm, GHSA-mfg7-5gfp-c4w3 io.netty:netty-codec-dns no attacker-controlled input ad, ge 4
GHSA-38f8-5428-x5cv, GHSA-57rv-r2g8-2cj3, GHSA-f6hv-jmp6-3vwv, GHSA-hvcg-qmg6-jm4c, GHSA-m4cv-j2px-7723, GHSA-pwqr-wmgm-9rr8, GHSA-v8h7-rr48-vmmv, GHSA-xxqh-mfjm-7mv9 io.netty:netty-codec-http no attacker-controlled input (gateway re-encodes framing) ad, ge 16
GHSA-4mp9-239f-g9hg, GHSA-6cqp-g7gg-8hr5, GHSA-6jqx-86gh-f27w, GHSA-8c42-7qj2-3j46, GHSA-gcjf-9mgh-3p7g, GHSA-jppx-w49h-x2qq, GHSA-mvh2-crg5-v77c io.netty:netty-codec-http code not loaded ad, ge 14
GHSA-q4f6-jm68-57ww io.netty:netty-codec-http unreachable from entrypoint ad, ge 2
GHSA-563q-j3cm-6jxm, GHSA-5x3r-wrvg-rp6q, GHSA-93wv-jw9v-4972, GHSA-c2gf-v879-257j, GHSA-c69g-56f8-xwqj, GHSA-f6hv-jmp6-3vwv, GHSA-w9fj-cfpg-grvv io.netty:netty-codec-http2 unreachable from entrypoint (HTTP/2 off) ad, ge 14
GHSA-2c5c-chwr-9hqw, GHSA-4grm-h2qv-h6w6, GHSA-c2rx-5r8w-8xr2, GHSA-hpcc-26xq-25fv io.netty:netty-codec-http3 code not loaded (no HTTP/3) ad, ge 8
GHSA-3qp7-7mw8-wx86 io.netty:netty-handler code not loaded ad, ge 2
GHSA-c653-97m9-rcg9, GHSA-x4gw-5cx5-pgmh io.netty:netty-handler unreachable from entrypoint ad, ge 4
GHSA-45q3-82m4-75jr io.netty:netty-handler-proxy code not loaded ad, ge 2
GHSA-5pvg-856g-cp85, GHSA-676x-f7gg-47vc, GHSA-xmv7-r254-6q78 io.netty:netty-resolver-dns no attacker-controlled input ad, ge 6
GHSA-rwm7-x88c-3g2p io.netty:netty-transport-classes-epoll no attacker-controlled input ad, ge 2
GHSA-w573-9ffj-6ff9 io.netty:netty-transport-native-epoll code not loaded ad, ge 2
GHSA-q62f-h9x2-gcqc org.springframework.ai:* (scored SCHEDULE; see Moderate table) 0
GHSA-8v8j-3hxp-93wr org.springframework.boot:spring-boot code not loaded cu, ve, vi, cf, di, ad, ge 7
GHSA-wwpq-f5c3-7hvx org.springframework.boot:spring-boot advisory precondition unmet (session.persistent unset) cu, ve, vi, cf, di, ad, ge 7
GHSA-ggg2-9786-hwc8 org.springframework.boot:spring-boot-autoconfigure code not loaded cu, ve, vi, cf, di, ad, ge 7
GHSA-8hfc-fq58-r658 org.springframework.boot:spring-boot-starter-actuator advisory precondition unmet (no authorization rule exists) cu, ve, vi, di, ad, ge 6
GHSA-mgvc-8q2h-5pgc org.springframework.boot:spring-boot-starter-actuator code not loaded cu, ve, vi, di, ad, ge 6
GHSA-2mh5-3cw6-hrrq, GHSA-3qwq-q9vm-5j42, GHSA-6g23-24mc-hx6x, GHSA-86wq-234q-r6wg, GHSA-j6hh-h3cf-c2hf org.springframework.cloud:spring-cloud-config-server no attacker-controlled input (trusted config repo) cf 5
GHSA-659m-px2c-25wj org.springframework:spring-core no attacker-controlled input cu, ve, vi, cf, di, ad, ge 7
GHSA-5m4m-73w9-8433 org.springframework.data:spring-data-commons advisory precondition unmet (no @ProjectedPayload) cu, ve, vi, ge 4
GHSA-5vpf-xvv7-c8vh, GHSA-88fw-v6x4-3f58, GHSA-9fw2-h3hf-293r org.springframework.data:spring-data-commons unreachable from entrypoint cu, ve, vi, ge 12
GHSA-9f52-rjqv-25qv, GHSA-r5w3-xv2f-j59q, GHSA-wxpp-56q6-5pcg org.springframework:spring-expression no attacker-controlled input cu, ve, vi, cf, di, ad, ge 21
GHSA-7m2p-62gw-p8qq org.springframework:spring-web no attacker-controlled input cu, ve, vi, cf, di, ad, ge 7
GHSA-4773-3jfm-qmx3, GHSA-5843-p793-ghmm, GHSA-83f7-v6px-pp3h, GHSA-cjpg-rgq5-fr37 org.springframework:spring-webflux unreachable from entrypoint ad, ge 8
GHSA-6hcq-hmm3-jj3c org.springframework:spring-webflux no attacker-controlled input (SBA server-sent events) ad 1
GHSA-6hcq-hmm3-jj3c org.springframework:spring-webflux unreachable from entrypoint ge 1
GHSA-4hfh-6x8g-gwpp, GHSA-6p4f-wcwh-5vvm, GHSA-72pg-x5f8-j25j, GHSA-h3qp-gqrc-q736, GHSA-mq64-j8f9-9gcj, GHSA-wg35-8jpf-2xv3, GHSA-x23c-287f-qqv5 org.springframework:spring-webflux advisory precondition unmet (resource chain off; no /** view; no auth step) ad, ge 14
GHSA-3chg-m5w7-qfv5, GHSA-4773-3jfm-qmx3, GHSA-6hcq-hmm3-jj3c org.springframework:spring-webmvc unreachable from entrypoint cu, ve, vi, cf, di, ge 18
GHSA-cjpg-rgq5-fr37 org.springframework:spring-webmvc no attacker-controlled input cf, di 2
GHSA-cjpg-rgq5-fr37 org.springframework:spring-webmvc unreachable from entrypoint (WebFlux is the active stack) ge 1
GHSA-957g-f97v-vppc org.springframework:spring-webmvc code not loaded cu, ve, vi, cf, di, ge 6
GHSA-6p4f-wcwh-5vvm, GHSA-72pg-x5f8-j25j, GHSA-h3qp-gqrc-q736, GHSA-mq64-j8f9-9gcj, GHSA-wg35-8jpf-2xv3, GHSA-x23c-287f-qqv5 org.springframework:spring-webmvc advisory precondition unmet (resource chain off; Linux containers; no /** view) cu, ve, vi, cf, di, ge 36
GHSA-563x-q5rq-57qp org.apache.tomcat.embed:tomcat-embed-core no attacker-controlled input (gateway drops chunk extensions) cu, ve, vi, cf, di 5
GHSA-5m62-pw8w-7w9f org.apache.tomcat.embed:tomcat-embed-core advisory precondition unmet (no security constraints declared) cu, ve, vi, cf, di 5
GHSA-r29c-68gh-xp6x org.apache.tomcat.embed:tomcat-embed-core unreachable from entrypoint (HTTP/2 off) cu, ve, vi, cf, di 5
GHSA-5mp6-jrq3-r938, GHSA-9m3c-qcxr-9x87, GHSA-9m89-8frq-c98c, GHSA-fv25-8xcx-gqjc, GHSA-gx5v-xp9w-j4cg, GHSA-h6fc-48rj-7qqh, GHSA-mgp5-rv84-w37q, GHSA-rv64-5gf8-9qq8, GHSA-x4m4-345f-5h5g org.apache.tomcat.embed:tomcat-embed-core code not loaded (WebDAV, AJP, DIGEST, LockOutRealm, JSON access log, clustering, Tomcat Native/OCSP, WebSocket client) cu, ve, vi, cf, di 45
GHSA-563x-q5rq-57qp, GHSA-5m62-pw8w-7w9f, GHSA-5mp6-jrq3-r938, GHSA-8mc5-53m5-3qj2, GHSA-9m3c-qcxr-9x87, GHSA-9m89-8frq-c98c, GHSA-fv25-8xcx-gqjc, GHSA-gx5v-xp9w-j4cg, GHSA-h6fc-48rj-7qqh, GHSA-mgp5-rv84-w37q, GHSA-r29c-68gh-xp6x, GHSA-rv64-5gf8-9qq8, GHSA-x4m4-345f-5h5g org.apache.tomcat.embed:tomcat-embed-core code not loaded (Tomcat never constructed; reactive web stack) ge 13
GHSA-c9ph-gxww-7744, GHSA-r4v4-5mwr-2fwr, GHSA-xjw8-8c5c-9r79 org.thymeleaf:thymeleaf no attacker-controlled input ad 3
GHSA-c9ph-gxww-7744, GHSA-r4v4-5mwr-2fwr, GHSA-xjw8-8c5c-9r79 org.thymeleaf:thymeleaf-spring6 no attacker-controlled input ad 3

Appendix: Alert dismissal commands

This appendix is for the operator executing the deferrals: the ready-to-run record.

The alert list supplied for this run has no system of record attached. It arrived as a JSON array with no repository owner, no alert numbers, and no API endpoint, so no dismissal API can be addressed and no per-alert command can be emitted. Where the alerts came from GitHub Dependabot, the shape of each dismissal is:

gh api --method PATCH /repos/{owner}/{repo}/dependabot/alerts/{alert_number} \
  -f state=dismissed \
  -f dismissed_reason=not_used \
  -f dismissed_comment='<rationale, 280 ASCII characters max>'

Use dismissed_reason=not_used for the 162 not-loaded and the 155 unreachable findings, and dismissed_reason=vulnerable_code_not_actually_used where your tracker offers it for the 89 precondition-unmet and 169 first-party-input findings. Do not dismiss the two REVIEW findings.

One rationale per deferral group, each already inside GitHub's 280-character dismissed_comment limit. State the basis once per comment; a basis restated in different words spends the budget without adding evidence.

  • Group 1, code not loaded: k9 rubric 2026.08.24-v27: DEFER. Vulnerable code is not on the running classpath or is never constructed in this service. Not in KEV; EPSS below the p99 imminent-threat line. Residual Low 20/100, inherent 80, 60 points retired. Basis: code_not_loaded.
  • Group 2, unreachable: k9 rubric 2026.08.24-v27: DEFER. No path reaches the vulnerable code from any entry point this service exposes. Not in KEV; EPSS below the p99 imminent-threat line. Residual Low 20/100, inherent 80, 60 points retired. Basis: unreachable_from_entrypoint.
  • Group 3, precondition unmet: k9 rubric 2026.08.24-v27: DEFER. The advisory's own trigger condition is not met in this deployment; see the triage report for the specific condition. Not in KEV; EPSS below p99. Residual Low 20/100, inherent 80, 60 retired. Basis: advisory_precondition_unmet.
  • Group 4, first-party input only: k9 rubric 2026.08.24-v27: DEFER. The vulnerable code runs only on values from the application, operators, or internal backends; no untrusted actor supplies them. Not in KEV; EPSS below p99. Residual Low 20/100, inherent 80, 60 retired. Basis: no_attacker_controlled_input.
  • Group 5, undetermined with threat absent: k9 rubric 2026.08.24-v27: DEFER on threat. CVE-2026-32990 names no vulnerable symbol, so reachability is undetermined, not claimed. Not in KEV; EPSS p22.99, well below the p99 line. Residual Moderate 50/100, inherent 80, 30 retired. Basis: undetermined.

Until a system of record is attached, the durable rationale record is this report, together with the k9 scored-findings capture rows written for all 691 verdicts under the 2026-09-02+3858f9c630cf989bb6809a86edf47c2be78dc9f1 risk-context revision.