class MyPrecious::CVEs::Applicability_V4_0

Attributes

package[R]

Public Class Methods

new(package, configs) click to toggle source
Calls superclass method
# File lib/myprecious/cves.rb, line 123
def initialize(package, configs)
  super()
  self.update(configs)
  @package = package.downcase
end

Public Instance Methods

applies_to?(version) click to toggle source
# File lib/myprecious/cves.rb, line 134
def applies_to?(version)
  package_nodes(nodes).any? do |node|
    version_matches_node?(version, node)
  end
end
cpe_entry_indicates_vulnerable_version?(version, pattern) click to toggle source
# File lib/myprecious/cves.rb, line 188
def cpe_entry_indicates_vulnerable_version?(version, pattern)
  return false unless pattern['vulnerable']
  
  cpe_vendor, cpe_product, cpe_version, cpe_update = pattern['cpe23Uri'].split(':')[3,4]
  return false if (CVEs.config['blockedProducts'] ||= []).include?([cpe_vendor, cpe_product].join(':'))
  return false if cpe_product != @package
  if version == '*'
    return true
  end
  return false unless [nil, '*', '-'].include?(cpe_update) # We'll ignore prerelease versions
  if cpe_version != '*' && cpe_version == version
    return true
  end
  
  if (range_start = pattern['versionStartIncluding'])
    range_test = :<=
  elsif (range_start = pattern['versionStartExcluding'])
    range_test = :<
  else
    range_test = nil
  end
  if range_test && !version_compare(range_start, version).send(range_test, 0)
    return false
  end
  
  if (range_end = pattern['versionEndIncluding'])
    range_test = :<=
  elsif (range_end = pattern['versionEndExcluding'])
    range_test = :<
  else
    range_test = nil
  end
  if range_test && !version_compare(version, range_end).send(range_test, 0)
    return false
  end
  
  return range_start || range_end
end
each_vulnerable_cpe() { |cpe| ... } click to toggle source
# File lib/myprecious/cves.rb, line 154
def each_vulnerable_cpe
  return enum_for(:each_vulnerable_cpe) unless block_given?
  
  remaining = nodes.to_a.dup
  while (node = remaining.shift)
    if node['children']
      remaining.insert(0, *node['children'])
    else
      node['cpe_match'].each do |pattern|
        next unless pattern['vulnerable']
        cpe = pattern['cpe23Uri']
        if package_cpe_regexp =~ cpe
          yield cpe
        end
      end
    end
  end
end
make_comparable(ver_str) click to toggle source
# File lib/myprecious/cves.rb, line 234
def make_comparable(ver_str)
  ver_str.split('.').map {|p| p.to_i}
end
nodes() click to toggle source
# File lib/myprecious/cves.rb, line 130
def nodes
  self['nodes']
end
package_cpe_regexp() click to toggle source
# File lib/myprecious/cves.rb, line 173
def package_cpe_regexp
  /^cpe:2.3:a:[^:]*:#{package}(:|$)/
end
package_nodes(node_list) click to toggle source
# File lib/myprecious/cves.rb, line 146
def package_nodes(node_list)
  node_list.select do |node|
    node['children'] || node['cpe_match'].any? do |pattern|
      pattern['cpe23Uri'] =~ package_cpe_regexp
    end
  end
end
vendors() click to toggle source
# File lib/myprecious/cves.rb, line 140
def vendors
  Set.new(each_vulnerable_cpe.map do |cpe|
    cpe.split(':')[3]
  end)
end
version_compare(a, b) click to toggle source

Return a <=> b for version strings a and b

# File lib/myprecious/cves.rb, line 230
def version_compare(a, b)
  make_comparable(a) <=> make_comparable(b)
end
version_matches_node?(version, node) click to toggle source
# File lib/myprecious/cves.rb, line 177
def version_matches_node?(version, node)
  test = (node['operator'] == 'AND') ? :all? : :any?
  if node['children']
    return node['children'].send(test) {|child| version_matches_node?(version, child)}
  end
  
  return node['cpe_match'].any? do |pattern|
    cpe_entry_indicates_vulnerable_version?(version, pattern)
  end
end