class Bundler::Audit::Advisory

Represents an advisory loaded from the {Database}.

Public Class Methods

load(path) click to toggle source

Loads the advisory from a YAML file.

@param [String] path

The path to the advisory YAML file.

@return [Advisory]

@api semipublic

# File lib/bundler/audit/advisory.rb, line 50
def self.load(path)
  id   = File.basename(path).chomp('.yml')
  data = File.open(path) do |yaml|
           if Psych::VERSION >= '3.1.0'
             YAML.safe_load(yaml, permitted_classes: [Date])
           else
             # XXX: psych < 3.1.0 YAML.safe_load calling convention
             YAML.safe_load(yaml, [Date])
           end
         end

  unless data.kind_of?(Hash)
    raise("advisory data in #{path.dump} was not a Hash")
  end

  parse_versions = lambda { |versions|
    Array(versions).map do |version|
      Gem::Requirement.new(*version.split(', '))
    end
  }

  return new(
    path,
    id,
    data['url'],
    data['title'],
    data['date'],
    data['description'],
    data['cvss_v2'],
    data['cvss_v3'],
    data['cve'],
    data['osvdb'],
    data['ghsa'],
    parse_versions[data['unaffected_versions']],
    parse_versions[data['patched_versions']]
  )
end

Public Instance Methods

==(other) click to toggle source

Compares two advisories.

@param [Advisory] other

@return [Boolean]

# File lib/bundler/audit/advisory.rb, line 210
def ==(other)
  id == other.id
end
criticality() click to toggle source

Determines how critical the vulnerability is.

@return [:none, :low, :medium, :high, :critical, nil]

The criticality of the vulnerability based on the CVSS score.
# File lib/bundler/audit/advisory.rb, line 138
def criticality
  if cvss_v3
    case cvss_v3
    when 0.0       then :none
    when 0.1..3.9  then :low
    when 4.0..6.9  then :medium
    when 7.0..8.9  then :high
    when 9.0..10.0 then :critical
    end
  elsif cvss_v2
    case cvss_v2
    when 0.0..3.9  then :low
    when 4.0..6.9  then :medium
    when 7.0..10.0 then :high
    end
  end
end
cve_id() click to toggle source

The CVE identifier.

@return [String, nil]

# File lib/bundler/audit/advisory.rb, line 93
def cve_id
  "CVE-#{cve}" if cve
end
ghsa_id() click to toggle source

The GHSA (GitHub Security Advisory) identifier

@return [String, nil]

@since 0.7.0

# File lib/bundler/audit/advisory.rb, line 113
def ghsa_id
  "GHSA-#{ghsa}" if ghsa
end
identifiers() click to toggle source

Return a compacted list of all ids

@return [Array<String>]

@since 0.7.0

# File lib/bundler/audit/advisory.rb, line 124
def identifiers
  [
    cve_id,
    osvdb_id,
    ghsa_id
  ].compact
end
osvdb_id() click to toggle source

The OSVDB identifier.

@return [String, nil]

# File lib/bundler/audit/advisory.rb, line 102
def osvdb_id
  "OSVDB-#{osvdb}" if osvdb
end
patched?(version) click to toggle source

Checks whether the version is patched against the advisory.

@param [Gem::Version] version

The version to compare against {#patched_versions}.

@return [Boolean]

Specifies whether the version is patched against the advisory.

@since 0.2.0

# File lib/bundler/audit/advisory.rb, line 184
def patched?(version)
  patched_versions.any? do |patched_version|
    patched_version === version
  end
end
to_h() click to toggle source

Converts the advisory to a Hash.

@return [Hash{Symbol => Object}]

Calls superclass method
# File lib/bundler/audit/advisory.rb, line 219
def to_h
  super.merge({
    criticality: criticality
  })
end
unaffected?(version) click to toggle source

Checks whether the version is not affected by the advisory.

@param [Gem::Version] version

The version to compare against {#unaffected_versions}.

@return [Boolean]

Specifies whether the version is not affected by the advisory.

@since 0.2.0

# File lib/bundler/audit/advisory.rb, line 167
def unaffected?(version)
  unaffected_versions.any? do |unaffected_version|
    unaffected_version === version
  end
end
vulnerable?(version) click to toggle source

Checks whether the version is vulnerable to the advisory.

@param [Gem::Version] version

The version to compare against {#patched_versions}.

@return [Boolean]

Specifies whether the version is vulnerable to the advisory or not.
# File lib/bundler/audit/advisory.rb, line 199
def vulnerable?(version)
  !patched?(version) && !unaffected?(version)
end