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