Brendan McDevitt home about photos

cve.org CNA Security Advisories

The data:

The website hosted at cve.org has recently been revamped. They host the source code for the site at the following url.

I wanted to know the organization names of each CNA and if possible, where they post their vendor security advisories. I was looking for a URL to each advisory for each vendor. This is so I can look into what the actual vendor is saying when they are being notified of security vulnerabilities. To obtain this information, we can look through the source code used in the CVE Project website.

On the website itself if you search the ‘List of Partners’ found here you will find a hyperlink to a sub page for each organization name. As of writing this post, there are 211 partners.

An example of one of the organization names page looks looks like this. apache. Notice the ‘View Advisories’ link here under the Security Advisories section.

This This is what I was looking for.

It really is nice that they host the source code to their website in the open. Because of this, I can quickly pull this information that I want by writing a little bit of code. It’s just your standard GET request and parse a JSON file. I like Ruby and both Python but I have been using Ruby longer, so I use that more for pulling data quickly like the JSON data we are working with today. You can find the JSON file that the website uses to load the CNA information. We can write code that downloads this json file and parses it…like this!

#!/usr/bin/env ruby
# outputs the list of CNA organizationNames and the securityAdvisory urls from the json file here:
# https://raw.githubusercontent.com/CVEProject/cve-website/dev/src/assets/data/CNAsList.json

require 'json'
require 'rest-client'

class CnaSecurityAdvisories
  attr_accessor :url
  def initialize
    @url = 'https://raw.githubusercontent.com/CVEProject/cve-website/dev/src/assets/data/CNAsList.json'
  end

  def send_request_rest
    RestClient::Request.execute(
      method: :get,
      url: url
    )
  end

  def parse_res(response)
    JSON.parse(response.body)
  end

  def get_json
    res = send_request_rest
    if res.code == 200
      parse_res(res)
    else
      "HTTP Status: #{res.code}"
    end
  end

  def perform
    json = get_json
    json.map do |d|
      org_name = d.dig('organizationName')
      security_advisories = d.dig('securityAdvisories')
      security_advisory_urls = security_advisories.dig('advisories').map { |adv| adv.dig('url') }
      { orgName: org_name, security_advisories_urls: security_advisory_urls }
    end
  end
end

I usually will pull out pry and load the class in the console and run it like this to export the data to a new json file.

[3] pry(main)> data = CnaSecurityAdvisories.new.perform
[4] pry(main)> File.write('/home/booboy/cna_security_advisory_urls.json', data.to_json)
=> 25298

I have hosted this code at my gitlab. source code and json data