Module: StillActive::RubyAdvisoryDb

Extended by:
RubyAdvisoryDb
Included in:
RubyAdvisoryDb
Defined in:
lib/helpers/ruby_advisory_db.rb

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

Instance Method Summary collapse

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.



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/helpers/ruby_advisory_db.rb', line 42

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.message}) — run `bundle audit update` to repair the checkout")
  []
end

#loadObject

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.



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/helpers/ruby_advisory_db.rb', line 24

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.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/helpers/ruby_advisory_db.rb', line 58

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],
    source: "ruby-advisory-db",
  }
end