class Control

Constants

KNOWN_BAD_RULES

These rules don't have the cert/cwe number in description or have other problems If there is an error with them, ignore it since we know they have problems.

TAG_DATA

rubocop:disable Style/MutableConstant

Public Class Methods

new(control_key, findings, sonar_api, mappings) click to toggle source

@param [SonarQubeApi] sonar_api

# File lib/heimdall_tools/sonarqube_mapper.rb, line 193
def initialize(control_key, findings, sonar_api, mappings)
  @key = control_key
  @findings = findings
  @api = sonar_api
  @mappings = mappings

  @data = @api.query_rule(@key)
end

Public Instance Methods

_get_parsed_tags(tag_type) click to toggle source

Get specific tags for a given type. ex. for cwe, get the CWE numbers Output: [] # [“cwe-295”, …]

# File lib/heimdall_tools/sonarqube_mapper.rb, line 205
def _get_parsed_tags(tag_type)
  tag_data = TAG_DATA[tag_type]
  parsed_tags = []

  if tag_data.key? :regex
    # If the tag type has a regex, try to find the specified tag in the description
    # NOTE: Some tag types can have multiple matches, such as cwe
    reg = Regexp.new(tag_data[:regex], Regexp::IGNORECASE)
    parsed_tags += @data['htmlDesc'].scan(reg).map(&:first)

    if parsed_tags.empty? and not KNOWN_BAD_RULES.include? @key && parsed_tags.empty?
      puts "Error: Rule #{@key}: No regex matches for #{tag_type} tag."
    end
  else
    # If the tag type doesn't have a regex, it is specific enough to be mapped directly
    # Ex. Rule with tag owasp-a1 can be mapped directly.
    parsed_tags = @data['sysTags'] & @mappings[tag_type].keys

    if parsed_tags.empty? and not KNOWN_BAD_RULES.include? @key
      puts "Warning: Rule #{@key}: Has #{tag_type} tag but no usable mapping found."
    end
  end

  parsed_tags
end
get_nist_tags() click to toggle source

Returns the a list of the NIST 800-53 control based on the tags

# File lib/heimdall_tools/sonarqube_mapper.rb, line 232
def get_nist_tags
  # Since we only care about the most important 800-53 control,
  # we check for tags in order of importance/specificity (cwe's, then owasp, etc. Same as order of tag_data)
  # and return a 800-53 control for the first tag we can map
  TAG_DATA.each do |tag_type, _|
    next unless @data['sysTags'].any? { |tag| tag.start_with? tag_type.to_s }

    parsed_tags = _get_parsed_tags tag_type
    next if parsed_tags.empty?

    parsed_tag = parsed_tags.find { |tag| @mappings[tag_type].key? tag }
    next if parsed_tag.nil?

    return [@mappings[tag_type][parsed_tag]].flatten.uniq
  end

  DEFAULT_NIST_TAG # Entries with unmapped NIST tags fall back to defaults
end
hdf() click to toggle source
# File lib/heimdall_tools/sonarqube_mapper.rb, line 251
def hdf
  # NOTE: Structure is based on fortify -> HDF converter output
  {
    title: @data['name'],
      desc: @data['htmlDesc'],
      impact: IMPACT_MAPPING[@data['severity'].to_sym],
      tags: {
        nist: get_nist_tags
      },
      results: @findings.map(&:get_result),
      code: NA_TAG, # This should be the inspec code for the control, which we don't have
      id: @key,
      descriptions: NA_ARRAY,
      refs: NA_ARRAY,
      source_location: NA_HASH
  }
end