Module: StillActive::CvssHelper
Overview
Computes a CVSS score from a vector string, across v2/v3/v4. deps.dev stores only CVSS 3.x, so a CVSS-4-only advisory (the flagship protobuf case) arrives with no numeric score; OSV carries the v4 vector, and this turns it into the number the SARIF security-severity and CycloneDX rating want.
cvss-suite is an OPTIONAL, undeclared dependency: it over-constrains its own deps
(an exact bundler pin, a bigdecimal ~> 3.1 cap), the poison-pill pattern
still_active itself flags, so hard-requiring it would force that liability on every
user and trip our own audit. CvssHelper soft-requires it; install cvss-suite (or run
the distribution that bundles it) to light it up.
Returns cvss-suite's overall_score: for the base-only vectors OSV publishes that
IS the base score, but a vector carrying threat/environmental metrics would fold
those in -- which is why the severity band floors at the authoritative GHSA label
(VulnerabilityHelper.advisory_severity) and this number never lowers it: the label
drives gating and SARIF level, the number only sharpens display. Fails safe: an
absent gem or an absent/unparseable vector yields nil, never a crash.
Instance Method Summary collapse
-
#available? ⇒ Boolean
Memoized soft-require: true once cvss-suite loads, false when it isn't installed.
- #score(vector) ⇒ Object
Instance Method Details
#available? ⇒ Boolean
Memoized soft-require: true once cvss-suite loads, false when it isn't installed.
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/helpers/cvss_helper.rb', line 43 def available? return @available unless @available.nil? @available = begin require "cvss_suite" true rescue LoadError false end end |
#score(vector) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/helpers/cvss_helper.rb', line 24 def score(vector) return unless available? return if vector.nil? || vector.to_s.empty? cvss = CvssSuite.new(vector.to_s) cvss.valid? ? cvss.overall_score : nil rescue StandardError => e # We only reach here with cvss-suite loaded (available?), so a raise is the # installed gem failing this call site -- an incompatible version, a renamed # `overall_score` -- not a bad vector, which cvss-suite reports via valid?. # Fail safe to nil (the number is display-only, never gates), but don't # swallow it: an opted-in-but-broken scorer that emitted nothing would read # as "no advisories are scored". Warn once per run (not per advisory), # matching OsvClient.enrich rather than staying silent. warn_scorer_failed(e) nil end |