Class: Control

Inherits:
Object
  • Object
show all
Defined in:
lib/heimdall_tools/sonarqube_mapper.rb

Constant Summary collapse

TAG_DATA =

rubocop:disable Style/MutableConstant

{}
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.

%w{squid:S4434 squid:S2658}.to_set

Instance Method Summary collapse

Constructor Details

#initialize(control_key, findings, sonar_api, mappings) ⇒ Control

Returns a new instance of Control.

Parameters:



193
194
195
196
197
198
199
200
# 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

Instance Method Details

#_get_parsed_tags(tag_type) ⇒ Object

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



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# 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_tagsObject

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



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# 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

#hdfObject



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# 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