lib/release_tools/security/cves_issue.rb (90 lines of code) (raw):
# frozen_string_literal: true
module ReleaseTools
module Security
class CvesIssue
include ::SemanticLogger::Loggable
YamlError = Class.new(StandardError)
YamlMissingError = Class.new(YamlError)
YamlInvalidError = Class.new(YamlError)
YamlParseError = Class.new(YamlError)
delegate :title, to: :issue
# @param [Gitlab::ObjectifiedHash] issue is an object from the response of the issues list API
def initialize(issue)
@issue = issue
end
def impact
yaml.dig('vulnerability', 'impact')
end
def vulnerability_description
yaml.dig('vulnerability', 'description')
end
def credit
yaml.dig('vulnerability', 'credit')
end
def cvss_string
"CVSS:3.1/#{impact}"
end
def cvss_severity
cvss.severity
end
def cvss_base_score
cvss.base_score
end
def web_url
issue.web_url
end
def affected_versions
yaml.dig('vulnerability', 'product', 'affected_versions')
end
def pending_affected_versions?
affected_versions.nil? || affected_versions.include?('TODO')
end
def fixed_versions
yaml.dig('vulnerability', 'product', 'fixed_versions')
end
def pending_fixed_versions?
fixed_versions.nil? || fixed_versions.include?('TODO')
end
def yaml
return @yaml if defined?(@yaml)
unless yaml_present?
logger.error('CVE issue does not have YAML', issue: issue.web_url)
raise YamlMissingError, 'CVE issue does not have YAML'
end
@yaml = load_yaml
unless @yaml.is_a?(Hash)
logger.error('CVE issue YAML is not a Hash', issue: issue.web_url, yaml_str: yaml_str)
raise YamlInvalidError, 'CVE issue YAML is not a Hash'
end
@yaml
end
def yaml_str
issue.description.gsub(/^.*```yaml\n|\n```.*$/m, '')
end
def yaml_present?
yaml_str.present?
end
def valid_yaml?
load_yaml
rescue YamlParseError
false
end
def cve_id
return unless cve_label
cve_label.gsub('::', '-').upcase
end
private
attr_reader :issue
def cvss
CvssSuite.new(cvss_string)
end
def load_yaml
YAML.safe_load(yaml_str)
rescue Psych::DisallowedClass, Psych::BadAlias, Psych::SyntaxError => ex
logger.error('CVE issue contains invalid YAML', issue: issue.web_url, yaml_str: yaml_str, error: ex.inspect)
raise YamlParseError, 'CVE issue contains invalid YAML'
end
def cve_label
issue.labels.find { |label| label.start_with?('cve::') }
end
end
end
end