131% more reported CVEs per day in 2026 than last year.

Vulnerabilities

How to reduce noise in vulnerability management

Noise is a finding that takes attention without changing what you do. Cut it at the source, in this order: an accurate inventory, deduplication, a smaller dependency footprint, exploitability context, and owner routing with policies. Then rank what is left. The order matters because each step makes the next one cheaper, and prioritization tools rank noise rather than remove it.

Updated

Where vulnerability noise comes from

Take one backlog and sort it by where each finding came from. The numbers below are illustrative, not a benchmark, but the categories are the ones teams find when they sample their own backlog.

Source of the finding Of 1,000 findings (illustrative) Step that removes it
Components you do not ship: lockfile and manifest entries, builder layers, dev and test tools 300 1. Make the inventory right
The same CVE reported by several tools, or once per repository 250 2. Count every finding once
Wrong matches: CPE name collisions, distribution backports 80 1. Make the inventory right
True findings that cannot be exploited in your product 150 4. Add exploitability context
True findings with no fix yet 70 5. A policy decision with an expiry
Findings with no owner 50 5. Route to an owner
Left to rank and fix 100 Prioritization

One distinction makes the rest of the page easier. Some of these findings are false positives: the finding is wrong, because the component is not there or the version is not affected. Others are noise: the finding is right but does not change what you do this week. They need different fixes, and mixing them up is how teams end up suppressing true findings or arguing over wrong ones.

False positive: the finding is wrong Noise: right, but not urgent
The component is not in what you ship The vulnerable code cannot be reached or triggered in your product
The match is wrong: a CPE collision, or a backported fix the version number hides No fix exists yet, or the product is internal and not exposed
Fix it by correcting the inventory and the matching Fix it with context, a recorded decision and an owner

Step 1. Make the inventory match what you ship

This is the biggest single lever, because every later step multiplies the inventory's errors. A component that is listed but never shipped produces a finding in every scanner, every repository and every release.

  • Record from the build. Build the inventory from what the release build actually used, not from manifests or a scan of the finished artifact. A build-time SBOM contains what the job fetched, including what no lockfile lists.
  • Identify components with PURLs. A package URL such as pkg:npm/[email protected] names the ecosystem, package and version exactly. Matching PURL-keyed advisories, such as the ecosystem advisories in OSV, removes the wrong matches that come from guessing a CPE from a product name.
  • Use distribution-aware matching for OS packages. Debian and other distributions backport security fixes to the version they shipped instead of upgrading, so the version number can look older than the upstream fix. Match against the distribution's own security tracker, not upstream version ranges.
  • Track completeness. Know when the inventory could not see something, rather than assuming it is complete. A missing component is worse than a noisy one: it produces no finding at all.

Worked example. A Node.js service's lockfile includes [email protected], a glob-matching library that test and build tools depend on. A lockfile scan reports CVE-2024-4067, a regular expression denial of service fixed in 4.0.8. The release job installs production dependencies only, with npm ci --omit=dev, so micromatch never enters the build that ships. A record of that build does not contain it, and the finding never reaches the backlog. The CVE is real; for this product, the finding is a false positive.

Step 2. Count every finding once

The same CVE arrives from the SCA tool, the container scanner and the SBOM platform, and once more for every repository that uses the library. Deduplicate on one key: package URL, version and CVE. For example, pkg:npm/[email protected] with CVE-2024-45296 is one finding, however many tools report it.

  • Count one finding per shipped artifact, not one per scanner.
  • Aggregate across builds and repositories, so a shared library's CVE is one decision applied everywhere, not forty tickets.
  • Consolidate overlapping scanners. A simple rule: dependency findings come from one SCA or SBOM source, image findings from one container scanner, findings in your own code from one SAST tool. If two tools report the same signal, keep the one closer to what ships (SAST vs SCA).

Step 3. Ship less

Every dependency you do not ship is a source of findings you never have to handle.

  • Remove unused dependencies. Most projects carry a few packages nothing imports any more.
  • Upgrade the package that pulls in the vulnerable ones. Express 4.19.2 pins [email protected] and [email protected], which carry CVE-2024-45590 and CVE-2024-45296. You cannot update them on their own without overrides. Express 4.20.0, released in September 2024, depends on the fixed versions, so one upgrade clears both (transitive dependencies).
  • Use minimal base images. Slim and distroless images contain fewer operating system packages, so fewer advisories apply. Container scanning covers the image-specific levers.
  • Pin and update deliberately. Lockfiles and digests make the inventory stable between builds.
  • Block builds that contain a known vulnerable version. A policy gate that stops the build keeps a vulnerable library out before it becomes a finding anyone has to triage.
example-service
└─ [email protected]          → upgrade to 4.20.0
   ├─ [email protected]    CVE-2024-45590
   └─ [email protected]  CVE-2024-45296

Step 4. Add exploitability context

What is left after steps 1 to 3 is real. Context decides which of it is urgent.

  • VEX. Record "not affected" once, with a justification, as a VEX statement, and reuse it across releases and customers. When customers forward their own scans of your product, the same records answer them: see scaling a PSIRT, and how to answer customers after a supply chain attack for reply templates.
  • Reachability, where your tools offer it, shows whether your code can call the vulnerable function. It helps, within limits (reachability analysis).
  • Exploitation signals. CISA KEV says a vulnerability is exploited in the wild; EPSS estimates how likely exploitation is in the next 30 days.
  • Exposure. An internet-facing product outranks an internal tool on a private network.

Step 5. Route findings to an owner, with a policy

  • Write thresholds as policy. Set severity and exploitability thresholds per product or repository in a policy, not as a dashboard filter one person applied.
  • Assign owners by repository or team, so every finding has someone who decides.
  • Decide "no fix available" explicitly: accept with an expiry date, mitigate, or replace the component. A finding with no fix should not sit open with no decision.

Developers ignore findings for four reasons: no owner, no context, no deadline, or the wrong channel. Teams we talk to describe engineering switching scanners off because the output was too noisy to read. Fix each reason: an owner per repository, the context from step 4 attached, a due date from the policy, and delivery where the team already works.

Noise reduction vs hiding risk

A smaller backlog is only better if it shrank for the right reasons.

  • Suppression without a reason and an expiry is hidden debt. It comes back in an audit or an incident, with nobody left who remembers why.
  • Severity floors hide wrong findings instead of removing them. "Nothing below CVSS 7" makes a false positive at CVSS 6 disappear and leaves one at CVSS 9 in place.
  • Every decision not to fix needs a record. Customers ask for it, and so do regulations such as the EU Cyber Resilience Act, which expects manufacturers to handle vulnerabilities across a product's support period.

How to measure it

  • Findings per shipped release, not per scan.
  • The share of findings acted on: fixed, mitigated or decided.
  • Closed as not affected with a VEX record, against suppressed without one.
  • Time from build to owner: how long a new finding waits before someone owns it.
  • The duplicate rate across tools.

A 50-finding sample you can run in an afternoon. Pick 50 open findings at random. For each, record whether the component ships in the release, whether another tool or repository reports the same finding, whether the match is correct, whether it is exploitable in your product, whether a fix exists and who owns it. The counts tell you which step to start with. Run the same sample again a quarter later. We do not quote industry benchmarks for these numbers, because no primary source supports one.

Where CRACI fits

CRACI works on steps 1 and 2, the build gate in step 3, and parts of steps 4 and 5, for software built in GitHub Actions.

  • The inventory. CRACI replaces your GitHub-hosted runners and records the packages each job actually pulled in, with a PURL per component and a completeness state per SBOM. Every component in a CRACI SBOM was in the build. That accuracy is about the SBOM's components; a matched CVE can still not affect your product. That is what VEX is for, and CRACI supports VEX.
  • One finding, many builds. Findings are aggregated across builds and repositories, and monitored SBOMs are re-evaluated continuously as new vulnerabilities are published.
  • Gates. Policy gates can stop a build in real time on findings, including a build that contains a specific CVE.
  • Triage and routing. Security teams triage findings in CRACI and route each one to the team that owns the fix.
  • Notifications. CRACI notifies the relevant people of a vulnerability and its severity.

CRACI does not offer reachability analysis, SAST or MTTR dashboards. See vulnerability tracking for the full capability, or see what your builds actually contain.

When CRACI is not the answer

  • Most of your noise is SAST findings in your own code. That is a SAST tuning problem.
  • Your backlog is mostly true, exploitable findings in shipped code. That is a remediation capacity problem, not a noise problem.
  • You need runtime context from production workloads. A CNAPP or runtime security tool answers that.

For the wider plan, see what to automate when CVE counts keep rising, and the live figures on CVE publication trends.

Reducing vulnerability noise: frequently asked questions

How do I reduce the number of vulnerability alerts?

Cut them at the source, in order: make the inventory match what you ship, deduplicate findings by package URL, version and CVE, ship fewer dependencies, add exploitability context such as VEX, KEV and EPSS, and route what is left to an owner under a written policy. Then prioritize.

Why does our scanner report thousands of vulnerabilities, and which ones matter?

Usually because it reports components you do not ship, reports the same CVE once per tool and repository, and guesses some matches wrong. The ones that matter are in components your release actually contains, are exploitable in your product, and are known or likely to be exploited.

How do I deduplicate findings from several security tools?

Key every finding on the package URL, the version and the CVE, and count one finding per shipped artifact. Aggregate across repositories so a shared library is one decision. Then give each kind of signal to one tool, so two scanners stop reporting the same thing.

Should we suppress vulnerabilities that have no fix?

Not silently. Make an explicit decision: accept the risk with a written reason and an expiry date, mitigate it, or replace the component. Then revisit it when a fix appears. A suppression without a reason and an expiry is hidden debt.

Is a vulnerability that no one has fixed for a year still noise?

Not necessarily. Age says nothing about risk. If it ships and is exploitable, it needs a decision and an owner. If it does not affect your product, record that as a VEX statement so it stops coming back. Either way, it should not sit open with no decision.

How do I stop developers ignoring security findings?

Give every finding an owner, the context to act on it, a deadline from a written policy, and deliver it where the team already works. Remove the noise first: developers stop reading a channel where most findings do not matter.

What is a good number of open vulnerabilities?

There is no reliable benchmark, and the raw count is the wrong measure. Track findings per shipped release, the share acted on, the share closed with a recorded reason, and how long known exploited vulnerabilities stay open in shipped software.

See what your builds actually contain

Book a demo and run one of your GitHub Actions workflows on CRACI. Get an SBOM of what the build actually pulled in, and the vulnerabilities in it.

Book a demo