Skip to main content

Build vulnerabilities (7.x Beta)

7.x Beta

Vulnerability scanning is new in 7.x and is fully server-side — the Gradle plugin does no scanning of its own and adds no DSL toggle. The scan runs against the dependencies blob the plugin uploads, so the only producer-side requirement is that dependencies capture be enabled (it is, by default).

How the scan runs

Bugsee's worker fires jobs.vuln_scan automatically as soon as the build's dependencies_status flips to 'ready'. The job:

  1. Downloads the dependency blob you just uploaded.
  2. Filters to type == "library" entries — project and file dependencies are skipped (they don't have Maven coordinates).
  3. Queries OSV.dev in batches of up to 1 000 packages — POST /v1/querybatch — for matching advisories on each group:name:version.
  4. For every advisory ID returned, fetches the full record via GET /v1/vulns/{id} so the dashboard can show summary text, severity, fixed-in versions, and references.
  5. Cross-references GitHub Security Advisory (GHSA) when a backend GitHub token is configured, to pick up severity and freshness data that OSV sometimes lacks.
  6. Derives a numeric CVSS base score from the v3 / v3.1 vector when present.

The scan is automatic. There is no producer-side configuration to enable or disable it; if you want to suppress it, disable the parent dependencies capture (bugsee { buildInfo { dependencies { enabled.set(false) } } }).

What gets stored

The build record's vuln_scan_summary is an inline aggregate that drives the dashboard's chip strip:

{
"vuln_count": 7,
"affected_entries_count": 4,
"scanned_at": "2026-06-10T14:32:18Z",
"critical_count": 1,
"high_count": 2,
"medium_count": 3,
"low_count": 1,
"info_count": 0
}

The full per-vulnerability blob — advisory ID, aliases (CVE / GHSA / OSV), severity, CVSS base score, summary, fixed-in versions, references, and the list of affected dep IDs — lives in S3 under the customer's per-build prefix and is loaded on demand when you open a vuln-detail dialog.

What you see in the dashboard

Vulnerabilities surface inside the Dependencies tab of the build detail page, between the dependencies chip strip and the per-dependency table.

Strip states

The strip's render depends on vuln_scan_summary and vuln_scan_status:

  • In progressvuln_scan_status == 'scanning'. A small inline progress hint is shown; if the most recent successful scan is stale (older than the current dependencies upload), a "scan is out of date" note appears.
  • Failedvuln_scan_status == 'failed'. A retry prompt appears (subject to the cooldown below).
  • Readyvuln_scan_status == 'ready' AND vuln_count > 0. Chips appear for Vulnerabilities (total vuln_count), Affected (affected_entries_count — number of dependency entries flagged), and severity-counted chips: Critical, High, Medium, Low, Info. Each severity chip uses the same color scheme as the rest of the Bugsee dashboard for cross-page consistency.
  • Ready, no findingsvuln_count == 0. A green confirmation pill is shown.
  • Ready, summary only — when the inline summary is present but the detail blob hasn't been loaded yet, severity chips render but per-vuln drill-down isn't available until the lazy fetch completes.

Per-vulnerability dialog

Click a severity chip or a row in the affected-deps list to open the vuln-details dialog. It surfaces:

  • Severity badge (colored by Critical / High / Medium / Low / Info).
  • Advisory ID and aliases (GHSA-…, CVE-…, OSV-…).
  • CVSS base score (when derived from v3 / v3.1 vector).
  • Plain-language summary.
  • Fixed-in version range.
  • Reference URLs (advisory pages, commits, mailing-list threads).
  • The list of dependency entries in this build that are affected.

Manual re-scan

The build detail header's overflow menu offers a "Scan for vulnerabilities" action that re-runs the OSV scan against the same dependencies blob. Two cooldowns guard this:

  • 3-hour cooldown on vuln_scan_at (last successful scan timestamp). If the most recent successful scan is younger than 3 h, the menu item is disabled with a tooltip explaining when the next re-scan is allowed. This prevents accidental bursts of OSV.dev traffic from rapid clicks.
  • 1-hour cooldown on vuln_scan_attempt_at (last attempt, successful or not). This keeps a failing scan from looping at high frequency.

Use the manual re-scan when:

  • You know an advisory was published recently and want to confirm it's now flagged on an older build.
  • A previous scan landed failed for a transient reason (OSV.dev rate limit, network hiccup).

How it interacts with build comparisons

When you view a build that has a previous neighbour, Bugsee shows the vuln diff alongside the dependencies diff:

  • New vulnerabilities — findings that weren't flagged on the previous build but are flagged here. These are the highest-signal entries — they correlate with a recent commit and are worth gating release on.
  • Resolved — findings that were flagged previously and no longer are. Useful for confirming a dep bump or removal actually closed the issue.
  • Unchanged — findings carried over from the previous build. These are typically transitives you can't easily upgrade — the diff view lets you de-prioritise them when triaging.

The vuln diff is gated on identical collection_config (same as the deps diff) — if your CI changed scope or maxCount between builds, the diff falls back to showing only the current build's findings.

Caveats

  • Maven-only. The scanner queries OSV against the Maven package universe. Project and file dependencies aren't scanned because OSV doesn't index source-only or local-jar artifacts.
  • No private advisories. OSV.dev mirrors public advisory databases (GitHub Security Advisory, NVD, distro security teams). Vulnerabilities disclosed only in private channels don't appear here.
  • Severity sometimes blank. When neither OSV nor GHSA exposes a CVSS vector for a given advisory (common for ancient CVEs or vendor-only disclosures), the entry lands in the Info bucket rather than being silently dropped, so you can still see the advisory exists.
Found an issue, typo, or wrong statement on this page? Report it now →