Module: StillActive::RubyAdvisoryDb
Overview
Optional second vulnerability source: rubysec/ruby-advisory-db, read through bundler-audit's own loader when the user has it installed. We are a consumer — no YAML parsing or version-range matching of our own. Advisories are mapped into the same shape as deps.dev results and merged by VulnerabilityHelper.
Verified against bundler-audit 0.9.3: Advisory CVSS scores live in #to_h (:cvss_v3 / :cvss_v2), not in dedicated methods; Database.new raises ArgumentError when the ~/.local/share/ruby-advisory-db checkout is absent.
Defined Under Namespace
Classes: GemRef
Constant Summary collapse
- STALE_AFTER_SECONDS =
30 days
30 * 24 * 60 * 60
- OLDER_THAN_FLAW_OPERATORS =
Requirement operators whose safe versions are OLDER than the flaw, i.e. not a forward fix a consumer can upgrade to. Anything else ("> X" etc.) is.
["<", "<="].freeze
Instance Method Summary collapse
-
#advisories_for(database:, gem_name:, version:) ⇒ Object
Maps advisories the database reports for gem_name@version into our vulnerability shape.
-
#load ⇒ Object
Returns a loaded bundler-audit Database, or nil when bundler-audit isn't installed or its advisory checkout is absent.
-
#to_vulnerability(advisory) ⇒ Object
Translates a bundler-audit Advisory into the deps.dev-compatible hash.
Instance Method Details
#advisories_for(database:, gem_name:, version:) ⇒ Object
Maps advisories the database reports for gem_name@version into our
vulnerability shape. Returns [] when the database is unavailable or the
version can't be parsed (e.g. a git sha). A malformed advisory in the
checkout (a corrupt/partial bundle audit update) is surfaced, not
swallowed — silently returning [] there would hide a missed vulnerability.
45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/helpers/ruby_advisory_db.rb', line 45 def advisories_for(database:, gem_name:, version:) return [] if database.nil? parsed = parse_version(version) return [] if parsed.nil? advisories = [] database.check_gem(GemRef.new(gem_name, parsed)) { |advisory| advisories << to_vulnerability(advisory) } advisories rescue Gem::Requirement::BadRequirementError => e warn("still_active: ruby-advisory-db has a malformed advisory for #{gem_name} (#{e.}) — run `bundle audit update` to repair the checkout") [] end |
#load ⇒ Object
Returns a loaded bundler-audit Database, or nil when bundler-audit isn't installed or its advisory checkout is absent. Never raises — a missing second source just means we fall back to deps.dev only.
27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/helpers/ruby_advisory_db.rb', line 27 def load require "bundler/audit" require "bundler/audit/database" database = Bundler::Audit::Database.new warn_if_stale(database) database rescue LoadError nil # bundler-audit not installed rescue ArgumentError warn("still_active: ruby-advisory-db not found — run `bundle audit update` to enable dual-source vulnerability data") nil end |
#to_vulnerability(advisory) ⇒ Object
Translates a bundler-audit Advisory into the deps.dev-compatible hash. bundler-audit has no CVSS vector, so cvss3_vector is always nil here.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/helpers/ruby_advisory_db.rb', line 61 def to_vulnerability(advisory) primary = advisory.ghsa_id || advisory.cve_id || advisory.id details = advisory.to_h { id: primary, url: details[:url], title: details[:title], aliases: advisory.identifiers.reject { |identifier| identifier == primary }, cvss3_score: details[:cvss_v3], cvss3_vector: nil, cvss2_score: details[:cvss_v2], # No safe version a consumer can upgrade TO: the correlation bundler-audit # + `bundle outdated` can't produce alone. A factual read of the DB. no_fix_available: no_forward_fix?(advisory), source: "ruby-advisory-db", } end |