Skip to content

Add CVE chart filtering and non-critical CVE data collection (backend) - #47470

Merged
sgress454 merged 5 commits into
mainfrom
sgress454/44746-add-cve-filtering
Jun 19, 2026
Merged

Add CVE chart filtering and non-critical CVE data collection (backend)#47470
sgress454 merged 5 commits into
mainfrom
sgress454/44746-add-cve-filtering

Conversation

@sgress454

@sgress454 sgress454 commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Related issue: Resolves #44746

Details

  • Adds the ability to filter historical CVE data by software type, EPSS, CVSS, CVE ID (exclude only) and "has known exploit"
  • Hard-codes the CVSS filter to 9.0+ for now, since that's the only data that's been collected thus far
  • Un-gates the collection code so that it will collect CVE data for all severities (but still in the restricted set of software)

Related PRs update the front-end to allow sending these filters, and update GitOps to allow changing the default filters.

Checklist for submitter

If some of the following don't apply, delete the relevant line.

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.
    See Changes files for more information.

  • Input data is properly validated, SELECT * is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters.

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

Manual test plan — CVE chart filtering (backend smoke test)

Setup

  • Premium dev server running with a few hosts carrying vulnerable software (so cve_meta / software_cve /
    operating_system_vulnerabilities are populated)
  • Chart data present — collector ran once, or seeded: go run ./tools/charts-backfill --dataset cve --use-tracked-cves --days 7
  • API token exported and helper set:
    BASE=https://localhost:8080/api/v1/fleet/charts
    peak() { curl -sk -H "Authorization: Bearer $TOKEN" "$BASE/$1" | jq '[.data[].value] | max'; }
    

Checks (compare against the no-filter baseline)

  • Baseline returns data — GET /charts/cve?days=7 returns a data series; .filters is empty/default
  • Severity force-pinned to critical — cve?days=7 and cve?days=7&severity_min=0&severity_max=10 give identical
    peaks (no low-severity leak; client severity ignored)
  • Category narrowing — software_categories=browsers ≤ baseline; software_categories=os,browsers,office,adobe ==
    baseline
  • OS category includes kernel — software_categories=os returns OS-vuln + Linux-kernel CVE counts
  • Known-exploit narrowing — known_exploit=true ≤ baseline
  • EPSS narrowing — epss_min=0.9 ≤ baseline; epss_min=0&epss_max=1 == baseline (EPSS is 0.0–1.0 on the API)
  • Exclude is subtractive + tolerant — excluding a visible CVE lowers/keeps counts; exclude_cves=CVE-0000-00000
    == baseline (no-op)
  • Filters echo back — filtered requests return applied values under .filters
  • Uptime untouched — GET /charts/uptime?days=7 returns its normal series
  • Free-tier safety (optional) — on non-Premium, /charts/cve returns an empty series, no error
  • > 0 rows from:
    SELECT COUNT(DISTINCT scd.entity_id) AS below_critical
    FROM host_scd_data scd JOIN cve_meta cm ON cm.cve = scd.entity_id
    WHERE scd.dataset='cve' AND cm.cvss_score < 9.0;
  • (confirms lower-severity CVEs are stored)

Summary by CodeRabbit

Summary of changes

  • New Features

    • Added advanced CVE chart request filters: software categories, known-exploit flag, EPSS min/max, severity min/max, and excluded CVEs.
    • Expanded CVE chart coverage to use the full “collectible” CVE set, with filtering applied when serving chart data.
  • Tests

    • Added coverage for collecting collectible CVEs and resolving chart entities based on filter combinations and exclusions.
  • Chores

    • Updated CVE chart backfill to use collectible CVE discovery.

@sgress454

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR refactors the CVE chart data flow by replacing a single TrackedCriticalCVEs method with a two-phase pattern: CollectibleCVEs returns the full curated universe of CVE IDs across all severities, and ResolveCVEChartEntities applies read-time filters (software category, CVSS/EPSS bounds, known-exploit flag, CVE exclusions) to produce a display-ready allow-set. Changes span API contracts introducing MetricCVE constant and CVE category constants, HTTP request/response types with CVE-specific filter fields, MySQL datastore implementation with software matchers categorized by CVECategory* constants, service layer entity resolution that hard-codes CVSS critical-only bounds (9.0–10.0) while forwarding other filter predicates, bootstrap helpers, and comprehensive test coverage validating collection scope and filter resolution across all dimensions.

Possibly related PRs

  • fleetdm/fleet#45813: Both PRs update the CVE chart GetChartData read-path logic to move away from TrackedCriticalCVEs for entity-ID selection; this PR implements the new entity resolution path while the related PR removes the call entirely.
  • fleetdm/fleet#45247: Both PRs refactor the CVE collection scope in CVEDataset: the related PR constrains collection to tracked critical CVEs, while this PR broadens the collection to a "collectible" universe and defers narrowing to read-time resolution via ResolveCVEChartEntities.
  • fleetdm/fleet#45709: Both PRs modify the charts CVE-collection plumbing in server/chart/bootstrap and server/chart/api: the related PR adds a TrackedCriticalCVEs helper, while this PR removes it and replaces it with CollectibleCVEs/ResolveCVEChartEntities.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: adding CVE chart filtering capability and non-critical CVE data collection to the backend.
Linked Issues check ✅ Passed The code changes fully implement the engineering requirements from #44746: REST API changes for CVE filtering, no database migrations, no contributor API changes, comprehensive testing completed, and Premium-only gating confirmed.
Out of Scope Changes check ✅ Passed All code changes are directly related to implementing CVE chart filtering: API additions, database query updates, filter propagation, and test coverage. No unrelated modifications detected.
Description check ✅ Passed PR description follows the template structure with related issue, details, and completed checklist items. All required sections are present and properly filled out.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sgress454/44746-add-cve-filtering

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.11864% with 27 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.23%. Comparing base (4d82562) to head (674db54).
⚠️ Report is 132 commits behind head on main.

Files with missing lines Patch % Lines
server/chart/internal/mysql/charts.go 81.81% 8 Missing and 8 partials ⚠️
server/chart/internal/service/handler.go 0.00% 7 Missing ⚠️
server/chart/bootstrap/bootstrap.go 0.00% 2 Missing ⚠️
server/chart/internal/service/service.go 88.23% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #47470      +/-   ##
==========================================
+ Coverage   67.20%   67.23%   +0.03%     
==========================================
  Files        3393     3401       +8     
  Lines      228256   229193     +937     
  Branches    11755    11755              
==========================================
+ Hits       153396   154101     +705     
- Misses      61034    61203     +169     
- Partials    13826    13889      +63     
Flag Coverage Δ
backend 68.86% <77.11%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sgress454
sgress454 marked this pull request as ready for review June 14, 2026 17:16
@sgress454
sgress454 requested a review from a team as a code owner June 14, 2026 17:16
Copilot AI review requested due to automatic review settings June 14, 2026 17:16
@sgress454 sgress454 changed the title add CVE chart filtering Add CVE chart filtering and non-critical CVE data collection (backend) Jun 14, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
changes/44746-collect-and-filter-more-cves (1)

1-1: 💤 Low value

Consider clarifying the scope of filtering capabilities.

The entry accurately describes the data collection expansion and default filtering behavior. However, it could be clearer that this change also introduces interactive filtering capabilities (by software category, known-exploit status, EPSS score, and CVE exclusions) rather than just a fixed default filter, and that the feature is restricted to Fleet Premium tier.

📝 Suggested enhancement for clarity
-- Started collecting non-critical CVEs, filtering them out of charts by default.
+- Started collecting non-critical CVEs while maintaining critical-only chart display. Added Premium-tier filtering by software category, known-exploit status, EPSS score, and CVE exclusions.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@changes/44746-collect-and-filter-more-cves` at line 1, The changelog entry
for the CVE collection and filtering feature in the file
changes/44746-collect-and-filter-more-cves is incomplete. Update the entry to
clarify that in addition to the default filtering behavior, the feature includes
interactive filtering capabilities that allow users to filter by software
category, known-exploit status, EPSS score, and CVE exclusions. Also add an
explicit note that these filtering capabilities are restricted to the Fleet
Premium tier. This will provide users with a more complete understanding of what
functionality has been added and any tier-related limitations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@changes/44746-collect-and-filter-more-cves`:
- Line 1: The changelog entry for the CVE collection and filtering feature in
the file changes/44746-collect-and-filter-more-cves is incomplete. Update the
entry to clarify that in addition to the default filtering behavior, the feature
includes interactive filtering capabilities that allow users to filter by
software category, known-exploit status, EPSS score, and CVE exclusions. Also
add an explicit note that these filtering capabilities are restricted to the
Fleet Premium tier. This will provide users with a more complete understanding
of what functionality has been added and any tier-related limitations.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c7dbf764-500e-4b0d-9d9c-6bd4df4ef3b1

📥 Commits

Reviewing files that changed from the base of the PR and between a390fd5 and 2f4954f.

📒 Files selected for processing (2)
  • changes/44746-collect-and-filter-more-cves
  • server/chart/api/chart.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/chart/api/chart.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

This PR expands CVE chart data collection to include a wider, curated universe of CVEs (all severities) and adds read-time filtering so the vulnerability exposure chart can be narrowed by software categories, EPSS bounds, known-exploit status, and excluded CVEs (while keeping the default display critical-only for now).

Changes:

  • Replace the “tracked critical CVEs” collector scope with a broader “collectible CVEs” set and introduce a resolver to compute the chart’s entity allow-set at read time.
  • Add CVE-related query parameters to the charts API handler/types and echo filter fields in responses.
  • Add/expand unit and MySQL-backed tests around CVE collection and filtering behavior.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tools/charts-backfill/main.go Update backfill tool to discover CVEs using the new collectible-CVE query.
server/chart/internal/types/chart.go Add CVEChartFilter and extend datastore interface for collection + resolution.
server/chart/internal/testutils/testutils.go Expand test DB truncation to include vulnerability-related tables.
server/chart/internal/service/service.go Resolve CVE entity allow-set at read time; include CVE filter fields in response.
server/chart/internal/service/service_test.go Update mocks/tests for new CVE resolver and collectible collection path.
server/chart/internal/service/handler.go Parse CVE filter query params into RequestOpts.
server/chart/internal/mysql/charts.go Implement CollectibleCVEs and ResolveCVEChartEntities with category/meta predicates.
server/chart/internal/mysql/cve_filter_test.go Add MySQL integration tests for collectible set + resolver filtering.
server/chart/datasets.go Use api.MetricCVE constant and switch collector to CollectibleCVEs.
server/chart/bootstrap/bootstrap.go Expose CollectibleCVEs helper for dev tooling.
server/chart/api/http/types.go Add CVE filter query parameters to request type.
server/chart/api/chart.go Add MetricCVE + category constants and RequestOpts/Filters fields for CVE filters.
changes/44746-collect-and-filter-more-cves Release note entry (content excluded from review).
Files excluded by content exclusion policy (1)
  • changes/44746-collect-and-filter-more-cves

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/charts-backfill/main.go Outdated
Comment thread server/chart/internal/service/service.go Outdated
Comment thread server/chart/internal/service/service_test.go
Comment thread server/chart/internal/service/service_test.go
Comment thread server/chart/internal/service/service_test.go
Comment thread server/chart/internal/service/service_test.go
Comment thread server/chart/internal/mysql/cve_filter_test.go
cdcme
cdcme previously approved these changes Jun 15, 2026

@getvictor getvictor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only did a cursory review. Performance is always a concern for vulns. Please make sure the test plan test performance for different variations of settings.

Comment thread server/chart/api/chart.go
// CVE entity filters (apply only to the MetricCVE metric).
SoftwareFilters []string
KnownExploit bool
// EPSS bounds are 0.0–1.0 (matching cve_meta.epss_probability); nil means

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we validate inputs against the bound on the backend?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the API yes, not at the query level

@sgress454
sgress454 merged commit c370a96 into main Jun 19, 2026
45 checks passed
@sgress454
sgress454 deleted the sgress454/44746-add-cve-filtering branch June 19, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Filtering for vulnerability exposure pt. 1

4 participants