BootUI
Try it
Setup
Features
Properties
AI agents
Ecosystem
GitHub
Try it
Setup
Features
Properties
AI agents
Ecosystem
GitHub
  • Get started

    • Try the sample app
    • Setup
    • Spring WebFlux
    • Quarkus
    • Activation and safety
    • Non-standard runtimes
    • Troubleshooting
  • Features

    • All features
    • Overview
    • Advisors
    • Runtime
    • Configuration
    • Database
    • Security
    • Services
    • Diagnostics
    • Developer tools
  • Reference

    • Properties
    • Framework support
    • AI agents
    • Command line
    • BootUI family
  • Diagnostic checks

    • Architecture
    • REST API
    • Spring
    • Hibernate
    • Database
    • Security
    • Vulnerabilities
    • Memory
    • Pentesting
    • GraalVM readiness
    • CRaC readiness
    • Quarkus
    • Quarkus security
  • Contributing

    • Repository
    • Specification
    • Implementation plan
    • Quarkus design notes
    • WebFlux design notes
  • Privacy

Vulnerabilities checks

The Vulnerabilities advisor looks up known advisories for locally discovered Maven coordinates. It does not probe the application for exploitability. Spring MVC, Spring WebFlux, and Quarkus share the report contract and neutral evidence interpretation; Spring and Quarkus retain their native HTTP/JSON adapters.

Security and Pentesting are separate advisors.

Where these rules come from

This catalogue records the evidence rules and complete audit disposition for #978, which concerns OSV interpretation and reporting rather than inventory repairs or a new scanner. That research submitted no dependency inventory and ran no external scan. #989 added evidence-based panel and Overview scoring, retaining the cached GET-only dismissal refresh.

The 2026 advisor audit (§ 2026 advisor audit) added CVSS v4.0 scoring with a v4-over-v3 preference, CRITICAL malicious-package (MAL-) advisories, and honest Quarkus inventory coverage. It was grounded in live OSV.dev Maven records and FIRST's reference calculator, and each change was reviewed by three independent models.

Reading the result

Each dependency exposes two flags: assessment.queryComplete, meaning all its query pages were exhausted, and assessment.detailAssessmentComplete, meaning every returned detail was interpreted or conclusively excluded as withdrawn. Successful withdrawal is distinct from absent, failed, capped, mismatched, malformed, and unresolved details.

A genuine no-match has both flags true and an empty retained advisory list. Copies made for dismissal and EPSS preserve the flags.

Known-severity findings, including NONE, or a fully assessed package establish evidence.usable. UNKNOWN stays visible and carries no penalty, but it cannot establish usability and it limits coverage even after dismissal. Inventory, query, and detail gaps qualify an otherwise usable known-findings score. See the shared score eligibility policy for the evidence contract and dismissal behavior.

No extra OSV or EPSS work runs on render.

Keep three kinds of evidence separate:

  1. Inventory coverage describes what the local provider could identify. Its reported COMPLETE is not independent verification of every runtime component; known provider overclaims remain deferred below.
  2. OSV scan status describes query/detail completion and whether the returned association can be interpreted. A positive package/version query remains the detection authority. Unsupported or contradictory detail evidence retains the finding, reports PARTIAL with an explanation, and cannot justify an unaffected verdict.
  3. Optional EPSS enrichment supplies a per-CVE prioritization signal. Its failures append an explanation without changing OSV status, CVSS severity, or finding counts.

NOT_SCANNED/DISABLED, ERROR, and PARTIAL are not clean scans. An empty partial finding list means only that no finding was retained in that partial result. Even a completed lookup does not prove the application safe, reachable code free of vulnerabilities, or the upstream database exhaustive.

The immutable DTO fields, routes, MCP tools, CLI commands, configuration defaults, and advisoryId::packageName dismissal identities do not change. Findings count advisory occurrences per dependency, not unique CVEs: different advisory IDs can describe the same CVE.

Package and affected-version interpretation

The engine consumes neutral evidence, not Jackson nodes or framework types. Its internal applicability has three outcomes: matched, not matched, and unresolved. Unresolved is never silently converted into not affected.

  • Match the ecosystem exactly as Maven and the package exactly as groupId:artifactId. The OSV package name * is the one literal wildcard value, for that ecosystem; arbitrary patterns such as org.example:* are not globs. Repository-specific Maven ecosystems and other ecosystems are not interchangeable with Maven Central.
  • Explicit versions membership and supported ranges form a union, across all matching affected entries. Only Maven ECOSYSTEM ranges are locally evaluated. SEMVER, GIT, unknown domains, and malformed evidence do not supply Maven upgrade targets or negative vulnerability verdicts.
  • Order range events using the existing Maven comparator, not SemVer or lexical order. introduced is inclusive; fixed is exclusive; last_affected is inclusive; limit is an exclusive scope boundary, not a fix. introduced: "0" precedes every version and limit: "*" is unbounded. Multiple limits expand scope rather than intersecting it. Equal introduced and last_affected boundaries describe an inclusive singleton, including Maven-equivalent spellings and either input order. Reintroduced intervals and unsorted events must be interpreted, not flattened.
  • Validate event shape: exactly one supported event type per event, an introduction in each range, and no coexistence of fixed and last_affected in an event array. Missing or unusable evidence remains unresolved.
  • Do not remove a query-derived advisory because local detail interpretation cannot establish its association. Omit unsupported package-specific claims, retain genuinely global severity where applicable, and explain incomplete or contradictory evidence through the existing scan status/message.

These are supported-domain interpretation rules, not a replacement OSV matching service. OSV documents case-sensitive queries and potentially fuzzy version matching. Provider-specific platform, reachability, and repository metadata are not independently evaluated. See OSV schema and the Maven ordering references below.

Severity: applicable assessments, CVSS v4 preferred over v3

Selection is a disclosed BootUI policy, not an OSV requirement to choose the maximum:

  1. Collect supported CVSS assessments from all applicable matching affected entries. If any is a valid v4 assessment, select the highest v4 score; otherwise select the highest valid v3 Base score. The preference spans the whole applicable set, so one entry's v3 number never competes with another entry's v4 number. An unrelated branch must not raise the installed version's severity.
  2. When no applicable package severity is supplied, apply the same v4-then-v3 selection to the top-level assessments.
  3. When applicable package severity is supplied but invalid or unsupported, do not borrow a conflicting top-level score from a dual-level record: OSV prohibits package-level and top-level severity coexisting. Retain the recognized top-level database_specific.severity label fallback, otherwise UNKNOWN.

v3 and v4 scores are never compared on one scale. Preferring the newer v4 assessment matches the source database: in a live OSV.dev sample of 217 GitHub Advisory Database (GHSA) records for common Maven packages, all 21 records carrying both vectors took their GitHub severity label from the v4 vector, whereas the v3 band disagreed (always higher) for 6 of them, for example GHSA-fpj8-gq4v-p354, CVSS v3 9.1 CRITICAL against GitHub's MODERATE (v4 6.3). The 16 v4-only records, an increasingly common shape for new advisories, now carry a numeric score instead of only the label.

CVSS_V3 vectors need a CVSS:3.0 or CVSS:3.1 prefix and all eight Base metrics. Accept valid metric orderings and optional Temporal/Environmental metrics, validate those optional values, but compute only the Base score. Scope-dependent equations and FIRST's one-decimal Roundup remain unchanged.

CVSS_V4 vectors need a CVSS:4.0 prefix and all eleven Base metrics (AV AC AT PR UI VC VI VA SC SI SA). Every segment is validated like v3: no duplicates, empty/trailing segments, unknown metrics, malformed segments, or invalid values, including the optional Threat, Environmental, and Supplemental metrics. The score is FIRST's MacroVector lookup and interpolation, ported from FIRST's BSD-2-Clause reference calculator and verified against it for all 104,976 Base metric combinations and 60,000 sampled Threat/Environmental vectors. The vector is scored as published: GitHub often supplies the Threat metric E:U, and its label reflects that CVSS-BT score (GHSA-5j33-cvvr-w245 is HIGH 7.2, not the 9.2 Base-only CRITICAL). Supplemental metrics never change a score.

A valid zero is NONE, not unknown. Positive scores use FIRST's LOW/MEDIUM/HIGH/CRITICAL bands, which are identical for v3 and v4. Recognized database-specific labels remain compatibility behavior for existing providers, not a universal OSV severity scale; MODERATE maps to MEDIUM. Bare numeric strings and CVSS v2 are not scored. Unsupported assessments retain the finding with a recognized database label or UNKNOWN. The stable DTO does not say which CVSS version produced score; full assessment vector/source provenance stays deferred.

Malicious-package advisories

The OSV ID prefix MAL- belongs to the OpenSSF Malicious Packages database, which OSV.dev serves for Maven, for example MAL-2025-191470 for org.mvnpm:posthog-node 4.18.1 (an npm worm republished through mvnpm). These records carry no severity and no database_specific.severity, so they previously read as UNKNOWN with no score penalty.

An advisory whose own ID starts with MAL- is reported as CRITICAL with a null score, never a synthesized 10.0, and its details lead with BootUI's removal guidance: remove the dependency rather than upgrading it, and treat any machine that installed or ran it, and its credentials, as compromised. An alias naming a MAL- ID does not trigger this. Package/version interpretation, unresolved evidence, PARTIAL status, and withdrawal exclusion are unchanged, so a withdrawn false-positive report is still excluded. The override is a BootUI priority policy, not a CVSS assessment.

Fix candidates: relevant interval and evidence-backed target

fixedVersions is a bounded list of reported upgrade candidates, not a promise of compatibility, artifact publication, reachability remediation, or an automated upgrade.

  • A candidate must come from a fixed event closing a supported affected interval containing the installed version. A fix from an unrelated branch or an open-ended installed interval is not enough.
  • The target must be positively comparable and newer under Maven ordering. An inconclusive comparison is not evidence that a fix is available.
  • Recheck each target against all matching affected entries, including explicit versions, overlapping intervals, and reintroductions. A candidate still affected anywhere, or unresolved under any relevant evidence, is not a verified target.
  • Neither last_affected nor limit identifies an upgrade; Git hashes, SEMVER ranges, and arbitrary range types do not become Maven fixes.
  • Filter relevant newer targets before de-duplication, Maven ordering, and the ten-candidate display limit. Unrelated old fixes must not crowd out a useful candidate.

fixAvailable=false and an empty fixedVersions list mean no candidate was established under these rules. They do not mean the installed dependency is safe, no upstream fix exists, or every upstream fixed event was absent.

For example, installed 1.5 with affected branches [1.0,1.9) LOW and [2.0,2.4) CRITICAL uses the first branch's severity and closing fix, not the second branch's assessment. If another matching entry explicitly lists 1.9 as affected, 1.9 cannot be presented as a verified upgrade.

OSV queries, details, and partial completion

Passive GET/report reads return local inventory or cached data; they never initiate an OSV or FIRST call. Explicit enabled scans send Maven package names, ecosystem, and installed versions to the configured OSV service; detail requests send advisory IDs. No application source, local paths, classpath contents, or credentials are submitted. Localhost/Host protection, cross-site-write checks, per-panel enable/read-only policy, and single-flight admission remain unchanged. A busy conflict preserves the cached report.

Distinct package/version inputs are capped before querying. Requests contain at most 1,000 queries, with per-query continuation tokens and at most 20 page rounds per chunk. Every successful page must have exactly one structurally valid result per submitted query; advisory references require nonblank IDs and tokens must be string/null. An empty result without a token completes a query; an empty token-bearing page does not.

Validated successful pages are retained incrementally. A later network, HTTP, JSON, shape/cardinality, timeout, or byte-bound failure preserves earlier pages, earlier completed queries in the same chunk, and earlier chunks, then reports PARTIAL. Failure before any valid query page returns ERROR while retaining local inventory. Remaining chunks are not attempted after a query failure. Token cycles terminate at the fixed page bound, not through retries.

packagesScanned counts only queries exhausted without a continuation token, including when the cap is reached. packagesSkipped counts only the configured max-packages omission, not failed or unfinished queries; explain those in the message. A retained page can contribute a finding even when its query is not yet counted as scanned.

Distinct advisory IDs are sorted and capped by max-advisories before detail fetching, with at most 10 requests active. This limits details, not the number of query matches. Repeated IDs are de-duplicated per dependency; missing or mismatched detail IDs count as failed fetches. Successful details survive other failures as PARTIAL. Withdrawn records are excluded at the detail stage because a detail GET can still return a withdrawn advisory.

Existing streaming response caps remain 5 MiB for querybatch and 1 MiB for details/EPSS, with configured per-request timeouts and no automatic redirect following. Configurable service bases remain supported, including loopback fixtures; this change adds no external destination. A per-request timeout is not a whole-scan deadline. Whole-scan deadlines, retry/backoff, and a cancellation-preserving redesign are deferred; existing interrupt handling and restoration remain the contract.

EPSS: independent, bounded, and explicit

When independently enabled, explicit scans extract canonical CVE IDs from the advisory's own ID and retained aliases (the DTO retains at most 20 aliases). De-duplicate IDs and use chunks whose comma-separated cve parameter is at most 2,000 characters. Disabled enrichment or no canonical CVEs makes no FIRST request.

Validate an object response root and array data, plus supplied numeric total, offset, and limit metadata. Empty bodies, malformed JSON/envelopes, non-success responses, and invalid rows are unavailable/incomplete enrichment, not exceptions that discard OSV findings. Rows must belong to the requested chunk; probability and percentile must both be finite and in [0,1]. Shared selection defensively validates these values too.

Honor pagination metadata, including when the service returns a smaller page than requested. Each chunk is bounded to at most min(20, requested CVE count) pages; detect lack of pagination progress rather than looping or declaring unreturned CVEs absent. Once a page supplies pagination metadata, subsequent pages must preserve it; a metadata-free continuation is incomplete, not a successful no-data result. Retain successful earlier pages and chunks on later failure. A successful exhausted query with no row is no data, not a returned zero. Append a requested/available/no-data summary, or an incomplete/failure summary, to scan.message without dumping the CVE inventory and without changing OSV scan status.

For a multi-CVE advisory, select the maximum AVAILABLE per-CVE probability, with the percentile from that same record and a stable CVE tie-break. A missing alias must not hide another alias's valid result; zero is an available score, not unknown. This maximum is a BootUI prioritization heuristic, not the combined probability that the advisory or application will be exploited. Probabilities are never summed or combined by multiplying complements.

EPSS estimates exploitation in the wild in the next 30 days, whereas CVSS describes severity if exploited. Probability and percentile are distinct. The unchanged DTO does not expose the selected CVE, score date, or model version; separate latest-data requests can straddle a daily update. Do not imply the scalar represents every alias, is date-pinned, or demonstrates zero risk.

Inventory limitations: explicitly deferred

Spring merges SBOM, Maven descriptors, and adjacent-POM/classpath evidence by coordinate/version with source priority for identical coordinates. That source is discovery provenance, not a dependency path. Quarkus uses a build-time runtime dependency model rather than an SBOM requirement.

Spring MVC and WebFlux enumerate archive candidates from both java.class.path and local file URLs in the application classloader hierarchy. This covers merged, extracted jarmode=tools --layers --launcher applications started through JarLauncher, whose library JARs may be absent from the classpath property. The census does not depend on each JAR having a manifest or Maven descriptor, search arbitrary directories, or open remote URLs. Archive identification counts remain distinct from SBOM package totals and OSV query completion; an SBOM with no enumerable archives still has UNAVAILABLE coverage.

An archive still unidentified after coordinate attribution is inspected once more, reading only its manifest and entry names and stopping at the first class outside the application's base packages. A nested BOOT-INF/lib/ entry is inspected only when stored uncompressed; only its central directory and a manifest of at most 64 KiB are read, never its other entries; the end record must end the archive exactly and the directory must parse to its declared size and count. An archive carrying META-INF/maven/ descriptors or bundling another archive is never first-party, single-segment base packages are ignored, and when the Spring Boot layers.idx (fat JAR, merged extraction, or the sibling application/ of an in-place layered extraction) defines an application layer, only archives Boot's first-match rule assigns to that layer qualify; a present but unreadable index admits none. An archive the index positively places in application may also use each base package's parent when that parent has at least two segments (sibling modules of a launcher subpackage). An archive with at least one class, every class in the @SpringBootApplication base packages, is reported as first-party (archivesFirstParty, at most 200 firstPartyArchives names plus truncation) and does not count against COMPLETE; it is the application itself and is not scanned. spring-boot-jarmode-tools, which Spring Boot adds at packaging time, is identified from its manifest only when the file name, Implementation-Title: Spring Boot Jarmode Tools, and Implementation-Version agree and every class it carries is under org/springframework/boot/jarmode/tools/ (with no bundled archive), and is then scanned. For first-party recognition, unreadable, resource-only, compressed-nested, and oversized (more than 20,000 entries) archives, archives outside the layers-index application layer, a bare name that two different archives carry (the census counts it once), and every archive when no usable base package is detected, stay unidentified. Extracted WEB-INF/lib/ archives honor an adjacent WEB-INF/layers.idx the same way. Plain extract without --layers writes no index, so only the unwidened base packages apply there. Without a layers index, a library relocated into the application's own package and stripped of its Maven descriptors cannot be told apart from application code.

Neither provider supplies a verified runtime graph. Spring's filename census de-duplicates bare filenames and uses case-insensitive matching without group identity, so ambiguous classifiers/same-basename archives can overstate identified coverage. PURL form decoding can turn literal + into a space; malformed escapes and namespace rewriting need separate fixes. SBOM traversal caps resolved distinct coordinates, not inspected nodes, and parses the whole JSON first; it is not a whole-document traversal/memory bound. Components the SBOM declares not shipped (CycloneDX scope: "excluded", or the cdx:maven:package:test=true property the CycloneDX Gradle plugin sets on test-classpath libraries it lists by default), with their nested components, are left out unless the archive census finds their JAR (#1177); other components are not rigorously filtered to live runtime scope, and conflicting versions can remain.

Quarkus reports COMPLETE only for a wholly decoded build-time model. A missing or blank model key (the build step never ran; a real Quarkus application always has runtime JARs), a malformed entry, or a runtime JAR coordinate the build step could not encode (counted in bootui.internal.dependencies-skipped) reports UNAVAILABLE coverage and keeps every readable dependency. UNAVAILABLE is used rather than INCOMPLETE because the panel's unidentified-JAR copy and SBOM advice describe classpath archives, not model entries. Unreadable container/repackaged archives and missing Spring census information still require more precise diagnostics; consumers must not equate a reported COMPLETE with independently verified inventory completeness.

Coverage still transports exact reported counts and at most 200 unidentified names with truncation information. An SBOM can help identify artifacts without Maven descriptors, but is not proof of full coverage. No hash lookup, external coordinate resolution, shaded-library bytecode discovery, dependency-path graph, or reachability analysis is added.

Complete audit disposition

KEEP preserves an intentional behavior; UPDATE belongs to #978; DEFER is a known limitation not repaired here; HANDOFF records the original central-scoring boundary (implemented by #988/#989 below). IDs below identify audit rows, not public finding IDs. Mixed dispositions intentionally preserve an existing behavior while acknowledging its unresolved limitations.

Inventory

IDDispositionBehavior and boundary
INV-01KEEPMerge Spring discovery sources with priority for identical coordinates; source is not dependency-path provenance.
INV-02KEEP / DEFERCoordinate-only Maven PURL lookup ignores qualifiers/subpath; stricter inventory parsing deferred.
INV-03DEFERLiteral-plus form decoding, malformed percent escapes, and slash-namespace rewriting can change identity.
INV-04DEFERSBOM recursion bounds resolved coordinates, not inspected nodes; whole-document parsing remains.
INV-05DEFERSBOM runtime scope/type attribution and conflicting-version precision; only excluded and test-only (cdx:maven:package:test) components are filtered, unless their JAR is found (#1177).
INV-06KEEP / DEFERRetain readable Maven descriptors when siblings fail; malformed-properties/runtime exceptions and richer diagnostics deferred.
INV-07KEEPAdjacent POM must match artifact/version; parent group/version allowed; external entities, DTDs, and schema access blocked.
INV-08KEEPInfer group only below literal repository; filename must match artifact/version with optional classifier.
INV-09KEEPCensus conventional/manifest-selected nested libraries or classpath JARs without extracting nested contents; only still-unidentified archives have their manifest and entry names read.
INV-10DEFERBare-filename de-duplication, case-insensitive attribution, descriptor-owner attribution, and classifier ambiguity can overclaim coverage.
INV-11KEEP / DEFERPreserve unavailable census and unreadable names; repackaged/container/outer-filename fallback precision deferred.
INV-12KEEPExact reported coverage counts, at most 200 unidentified names, explicit truncation.
INV-13KEEPQuarkus non-production build-time model emits de-duplicated JAR coordinates and excludes malformed entries.
INV-14UPDATEA missing/blank Quarkus model, a malformed entry, or a build-time-skipped coordinate reports UNAVAILABLE, never COMPLETE (2026 audit).
INV-15KEEPExplicit non-capabilities: dependency paths, reachability, shaded-content discovery, and hash lookup.
INV-16KEEPArchives whose every class lives in the application's (multi-segment) base packages are first-party, counted and named (at most 200) separately, and never a coverage gap; one foreign class, a META-INF/maven/ descriptor, a bundled archive, or placement outside (or an unreadable) layers.idx application layer keeps an archive unidentified.
INV-17KEEPspring-boot-jarmode-tools is the only archive identified from its manifest, and only when file name, title, and version agree and it carries the jarmode tools classes.

Query and detail transport

IDDispositionBehavior and boundary
QRY-01KEEPPassive GET, explicit enabled POST, single-flight conflict preserving cache; inventory collection precedes admission.
QRY-02KEEPDe-duplicate package/version before cap; skipped is cap omission; minimum effective limit one.
QRY-03KEEPSend exact Maven ecosystem, package, and installed version, not local source/paths/credentials.
QRY-04KEEPAt most 1,000 queries/request and 20 page rounds/chunk, per-query tokens.
QRY-05KEEPValidate object results, exact cardinality, nonblank advisory IDs, and string/null tokens.
QRY-06KEEPEmpty valid result without a continuation token completes the query.
QRY-07KEEPInitial failure before any successful page is ERROR with local inventory.
QRY-08KEEPLater chunk failure preserves earlier chunks as PARTIAL and stops subsequent chunks.
QRY-09UPDATELater page failure retains earlier validated pages and completed queries in that chunk.
QRY-10UPDATEPage-cap accounting counts only exhausted queries; message explains unfinished work.
QRY-11KEEPToken cycles terminate at cap; repeated IDs are de-duplicated before details/report.
QRY-12KEEPPer-request timeout and strict streaming byte budgets: 5 MiB query, 1 MiB detail/EPSS.
QRY-13DEFERNo total elapsed scan deadline across chunks/pages/detail waves/enrichment.
QRY-14KEEPNo automatic redirects; encoded detail IDs; configurable bases; bounded error messages, not response-body dumps.
DET-01KEEPSorted distinct IDs, configured detail cap, concurrency ten, executor shutdown.
DET-02KEEPMissing/mismatched detail ID is a failed fetch.
DET-03KEEPRetain successful details when other fetches fail; PARTIAL rather than fabricated complete data.
DET-04KEEPNonblank withdrawal excludes a record; malformed withdrawal-field interpretation remains an upstream-schema limitation.
DET-05UPDATEInterpret query/detail association without dropping query matches on unsupported local evidence.
DET-06UPDATEAggregate applicable matching entries, not first severity/all flattened fixes.
DET-07UPDATETri-state explicit versions/range union with introduced, fixed, last_affected, and limit semantics.
DET-08UPDATEMaven ECOSYSTEM evidence only for local range evaluation and targets; no hash/SEMVER reinterpretation.

Fixes and severity

IDDispositionBehavior and boundary
FIX-01KEEPOnly fixed identifies a target, never last_affected or limit.
FIX-02UPDATECandidate closes installed affected interval and is unaffected across all matching entries.
FIX-03UPDATEFilter applicable/newer targets before de-duplication/order/ten-candidate truncation.
FIX-04KEEPExisting Maven comparator and test-only ComparableVersion oracle; no production Maven dependency.
FIX-05UPDATEInconclusive comparison no longer establishes fixAvailable; false is not an unaffected verdict.
SEV-01UPDATETyped CVSS_V3 (v3.0/v3.1 prefix) and CVSS_V4 (v4.0 prefix) only; no bare score inference (2026 audit).
SEV-02KEEPBase equations, scope-dependent PR, zero impact, integer-based Roundup.
SEV-03UPDATEValidate full vector, including optional metrics; reject empty/unknown/duplicate/invalid segments; Base-only scoring.
SEV-04UPDATEMaximum applicable package assessment, v4 before v3 across the whole applicable set; genuinely global fallback only; reject conflicting dual-level score borrowing.
SEV-05KEEPZero NONE, positive standard bands, MODERATE to MEDIUM, invalid labels UNKNOWN.
SEV-06KEEP / DEFERKeep unsupported v2 findings with label/UNKNOWN; a v2 calculator stays deferred.
SEV-07UPDATECVSS v4.0 scored as published with FIRST's reference algorithm, full validation, Supplemental metrics ignored (2026 audit).
SEV-08UPDATEOwn-ID MAL- advisories are CRITICAL with a null score and removal guidance; aliases never trigger it (2026 audit).

EPSS

IDDispositionBehavior and boundary
EPS-01KEEPExplicit independently enabled scan, canonical CVEs from own ID/retained aliases only.
EPS-02KEEPDe-duplicated CVEs, 2,000-character chunks, explicit limit, request byte/time bounds.
EPS-03KEEPRequested IDs only; finite probability/percentile in [0,1]; missing is not zero; defend shared selection.
EPS-04UPDATEValidate root/data and pagination metadata; isolate malformed/empty envelopes as unavailable/incomplete enrichment.
EPS-05UPDATEMaximum AVAILABLE per-CVE probability, same-record percentile, stable tie-break; not combined likelihood.
EPS-06UPDATEBound pages/progress, retain earlier pages/chunks, append honest requested/available/no-data or failure summary; OSV status unchanged.
EPS-07DEFERSelected CVE/date/model provenance and cross-request date pinning require separate DTO work.
EPS-08KEEPAt most 20 retained aliases bounds enrichment scope; no claim to cover every upstream alias.

Reports, presentation, and API

IDDispositionBehavior and boundary
RPT-01KEEPImmutable DTOs; active findings determine counts; fixed severity ordering.
RPT-02KEEP / DEFERCount distinct advisory IDs per dependency; alias-cluster merging deferred to preserve identities. The 2026 sample observed no GHSA/CVE duplicate pairs for Maven queries.
RPT-03KEEPVersion-independent advisoryId::packageName dismissals; active counts/order; raw cached report unchanged.
RPT-04KEEPRestoring final dismissal returns original cached flags/counts.
RPT-05KEEPERROR may replace cache; DISABLED and busy conflict do not; EPSS failure must not lose OSV report.
UI-01KEEPInitial/disabled means not scanned, error unknown, partial means no finding in partial result—not clean.
UI-02KEEPSurface reported incomplete/unavailable inventory and max-packages omissions; provider limitations still apply.
UI-03HANDOFFResolved by #989: shared evidence-based eligibility and visible partial/non-score reasons in panel and Overview.
UI-04HANDOFFResolved by #988: Overview cached-report dismissal refresh using GET only; preserved by #989.
UI-05HANDOFF#989 averages only eligible advisor and GitHub scores, with a contributing count; missing evidence never supplies a fake zero or 100.
UI-06HANDOFF#989 retains incomplete Overview counts and explicit qualification/reasons instead of an idle hint.
UI-07DEFERBrowser's same-package lexical version sort differs from server Maven ordering; no second comparator.
UI-08UPDATEApplicable-target-only fix list; EPSS copy describes highest available per-CVE prioritization signal.
UI-09KEEP / DEFERBounded ADVISORY/FIX link priority and known alias links; reference-scheme normalization deferred.
API-01KEEPAll three stacks, configured mounts, localhost/Host/cross-site-write and read-only policy unchanged.
API-02KEEPREST/MCP/CLI share interpretation; names/schema stable, generated descriptions remain mechanical projections.

Regression obligations

These are acceptance cases for the implementation, not a claim that validation was run while writing this page:

  • Exact ecosystems/package/wildcard, repository-specific mismatch, multiple branches, explicit-list-only and union matches; unsorted/reintroduced intervals, all endpoint equalities, zero/infinite/multiple limits, malformed events, missing introductions, unsupported domains, and Maven qualifiers/aliases against the existing oracle.

  • Applicable low severity versus unrelated high severity; multiple applicable maximum assessments; invalid package severity with contradictory top-level score; global/database-label/zero/UNKNOWN fallbacks; valid optional CVSS metrics versus unknown, duplicate, empty, trailing, malformed, and invalid values.

  • Closing fix versus unrelated branch/open interval, explicit affected target/overlap/reintroduction, unknown comparison, and more than ten unrelated old fixes.

  • Completed query plus token-only query, later HTTP/JSON/cardinality/timeout/body-limit failure, first failure, later chunk failure, page cap/cycles/duplicate IDs, retained findings, and exact exhausted-query accounting.

  • Reversed CVE aliases, own CVE, missing first/all aliases, true zero, stable ties and matching percentile, invalid values/unrequested IDs, malformed/empty envelopes, short pages, stalled pagination, bounded pages, failed later pages/chunks, and disabled/no-CVE no-call behavior.

  • Equivalent neutral results through Jackson 3 and Jackson 2, unchanged cached/dismiss/restore identities and policy, no GET-triggered external calls, and retained partial browser rows with accurate local EPSS wording.

  • CVSS v4 scores equal to FIRST's calculator for every reachable MacroVector and sampled Threat/Environmental vectors, real GHSA vectors including E:U, zero impact, metric order, Supplemental metrics, and malformed vectors; v4 preferred over a higher v3 at the top level and across mixed applicable package entries, an invalid v4 falling back to v3, and an unrelated branch's v4 never displacing the applicable v3 assessment.

  • MAL- advisories CRITICAL with a null score, removal guidance, retained unresolved flags, and no alias or case-variant trigger, through both adapters.

  • Quarkus wholly decoded, missing, blank, malformed, and build-time-skipped models.

Scoring/Overview regressions cover partial and complete evidence, UNKNOWN-only dismissal, missing details, completed no-match dependencies, malformed metadata, exact penalties, qualified aggregates, and GET-only refresh. Inventory repair acceptance cases, total scan deadline, date/model provenance, reachability, automated upgrades, and presentation version sorting are deferred, not silently included in this evidence-interpreter change.

Sources and version caveats

The audit used official sources. OSV schema links below are pinned to revision b388a18021a32b55da40c31eaef9fd4ce780447d, whose documentation identifies schema 1.9.0. Rendered/current documentation may differ; old records can omit schema_version (default 1.0.0). Optional modern fields must not be assumed present in every advisory. API pagination thresholds and upstream model versions can change.

SourceWhat it establishes
OSV affected/package schemaEcosystem/package identity, Maven repository distinctions, multiple affected entries, literal wildcard.
OSV versions/ranges/evaluationExplicit/range union, domain ordering, inclusive/exclusive events, introduction zero and limit semantics.
OSV severityTyped vectors and mutually exclusive package/top-level assessments; maximum selection is BootUI policy.
OSV query and querybatchCase sensitivity, potentially fuzzy versions, ordered batch responses, detail fetch requirement, per-query tokens.
OSV OpenAPIService response contract and 1,000-query batch bound; errors are not empty success.
Maven version order and ComparableVersion 3.9.11 JavadocQualifier aliases, numeric transitions, separator nesting and release normalization, not SemVer 2.0. The repository's test-only 3.9.16 oracle remains the executable compatibility target, distinct from this versioned Javadoc.
FIRST CVSS 3.0, 3.1, and 3.1 user guideFull vector validation, Base metrics/equations, scope, optional metrics, Roundup, qualitative zero.
FIRST CVSS 4.0 and reference calculatorMacroVector calculation, metric values, CVSS-B/BT/BE/BTE nomenclature, and the BSD-2-Clause reference implementation BootUI ports and tests against.
OpenSSF Malicious Packages and OSV ID prefixesMAL- records and their Maven entries; a malicious package is removed, not upgraded.
GitHub Advisory Database CVSSGitHub's severity levels from CVSS v4 or v3; observed live in OSV.dev GHSA records to follow the v4 vector when both exist.
FIRST EPSS endpoint, global API contract, and FAQCVE parameter bounds, row identity, total/offset/limit, probability versus percentile, and no-data semantics.
FIRST EPSS data/model historyDaily updates; research recorded model v5 starting 2026-06-15. This is a dated upstream fact, not an API/DTO guarantee; API /v1 is not the model version.
Google SRE overload guidance and RFC 9110Concurrency, request deadlines, retries, and overall budgets are separate resilience decisions. No retries or total-scan timeout are introduced here.
PURL parsing and Maven typeCoordinate/percent-decoding context for deferred inventory defects. These main-branch links are mutable; no external coordinate resolver is added.

2026 advisor audit

The audit re-read every interpretation rule against the sources above and live OSV.dev data (15 common Maven packages at old versions, 217 GHSA records, plus the Maven entries of OpenSSF Malicious Packages). Every existing row above was kept or updated as marked. Three changes were made, each first reviewed by three independent models (GPT-6.1 Sol, Claude Opus 5, Grok 4.7), all three supporting each change with amendments that were applied:

ChangeKindReviewer amendments applied
CVSS v4.0 scoring, v4 preferred over v3 (SEV-01, SEV-04, SEV-07)FixPreference spans the whole applicable set; never compare v3 with v4; score vectors as published after the reviewers questioned Base-only scoring, which GitHub's E:U labels disproved; verify against FIRST for every MacroVector.
MAL- advisories are CRITICAL (SEV-08)Added signalPass the ID to the shared interpreter; own ID only; null score, never a synthesized one; removal guidance in details; unresolved evidence kept independent.
Quarkus coverage honesty (INV-14)FixCount build-time skipped coordinates; ignore blank tokens; use UNAVAILABLE instead of INCOMPLETE, whose copy describes JAR files and SBOMs.

Considered and deliberately not added:

CandidateReason
CISA KEV flagA second external source with a feed larger than the 1 MiB body bound, a DTO field, configuration, and UI on every stack. KEV (observed exploitation) is not equivalent to EPSS (predicted exploitation), but the cost outweighs the gain for now.
Alias/duplicate collapsingNo GHSA/CVE duplicate pairs observed for Maven queries; merging would change advisoryId::packageName dismissal identities (RPT-02).
CycloneDX scope: excluded filteringcyclonedx-maven-plugin emits excluded only with the non-default detectUnusedForOptionalScope; SBOM scope attribution stays deferred as INV-05. Superseded by #1177: the CycloneDX Gradle plugin lists test-classpath libraries by default, so excluded and test-only components are now filtered unless their JAR is found.
Version provenance for scoreNeeds a DTO change; the catalog documents that score is the selected CVSS version's score instead.

See the feature guide for the user workflow and specification §5.11 for the stable panel contract.

Prev
Security
Next
Memory