I heard from our software consulting engineers that our customers would like a risk meter that scores CISA vulnerabilities. So here is my implementation.
First off, CISA stands for Cybersecurity & Infrastructure Security Agency. You know it has to be secure with “security” twice in the name. The CISA mission is to work with partners to defend against today’s threats and collaborates to build a more secure and resilient infrastructure for the future; and, lead the national effort to understand, manage, and reduce risk to our cyber and physical infrastructure. It publishes a vulnerability catalog which can be obtained via an API endpoint. Here are some reasons why the CISA catalog should be used. If you’re interested, there is a small stand-alone program to obtain the CISA vulnerability catalog,
Here is an outline of how I created a “CISA Risk Meter:”
- Obtain the CISA vulnerability catalog labeled by a CVE ID.
- Create a risk meter that has a CISA custom field criteria
- For each CVE ID in the CISA catalog, find the Kenna vulnerabilities associated with the CVE ID and mark the vulnerability’s CISA custom field so a risk meter will pick it up.
The code for this blog is in
blog_build_cisa_risk_meter.py; however, the latest code is at
build_cisa_risk_meter.py. And remember, a risk meter score is the vulnerability score of an asset group. The terms risk meter and asset group are used interchangeably.
Logging is used throughout the program. The log is in the file
cisa_vulns.log. It is not cleared or managed, so you will have to clean it up from time to time.
Check for Custom Field
The first thing the program does is check to see if the “CISA” custom field is present in:
check_for_custom_field() on line 65. I was disappointed to discover that custom fields can only be created in the UI. After a custom field is created, it is assigned a custom field ID and a
none value. This search can be skipped if the custom field ID is entered on the command line.
The “Search Vulnerabilities” API is used to filter all vulnerabilities with the CISA custom field with the value of
none. Search parameters are in the URL query parameters with the format:
custom_fields:, and for our CISA example:
Here is the code:
Note the return HTTP error codes. Error code
422 means the CISA custom field is not present and needs to be created in the UI.
After error checking, the CISA custom field ID is obtained and returned. We only need the first vulnerability to obtain the custom field ID.
In the above code snippet,
get_custom_field() for the vulnerability. This function runs through all the custom fields of a vulnerability looking for a custom field name in our case “CISA,” and returns the CISA custom field or
None. Finally, in line 102, the custom field ID is extracted and returned.
Get CISA catalog
After the “CISA” custom field ID is obtained, the CISA vulnerability catalog is fetched in
get_cisa_catalog(). This function is straightforward, invoking the API endpoint,
https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.jsonand returning the CISA vulnerabilities along with a vulnerability count and request ISO 8601 date. Here is what one of the CISA vulnerabilities looks like:
The catalog is returned. Some fields are extracted for logging purposes, but the array of vulnerabilities is what we really want. Later in the code, you’ll see that for each CISA vulnerability, the CVE ID is used. This CVE ID is the link between CISA vulnerabilities and Kenna vulnerabilities.
Creating the CISA Risk Meter
As you may recall, risk meter creation was discussed in the blog, Automating Risk Meter Creation, where asset tags were used as criteria. Here vulnerability custom fields are used as criteria. But first, before a risk meter is created, the code checks to see if one already exists in
get_a_risk_meter() by the name, “CISA Exploited Vulnerabilities.”
get_a_risk_meter(), you’ll see the code takes into account there can be more than 100 risk meters. This is done by scanning through all the risk meter pages.
Note that the page number is in the query parameters and the maximum page size for risk meters is 100. If the risk meter is found, it is returned. However, if the “CISA Exploited Vulnerabilities” are not found, the code creates one in
The salient point in:
create_risk_meter() is the risk meter criteria.
The custom field key format which for me is
custom_fields:8114:CISA. This custom field key is located
vulnerability array as an element with the value of
vulnerability array also contains the vulnerability
status key with the value of
open. With the above risk meter criteria, the “Create Asset Group” API is invoked.
Search for CISA Vulnerabilities
Now with a risk meter in hand, it is time to run through all the CISA vulnerabilities and see what Kenna vulnerabilities are associated with each CISA vulnerability. As stated early, CISA vulnerabilities are unique by CVE ID.
The outer loop at line 386 goes through each CISA vulnerability. On line 310, the “Search Vulnerability” API is invoked with the search criteria being the CVE-ID. An array of Kenna vulnerabilities is returned.
The inner loop at line 316 goes through each Kenna vulnerability for the CISA vulnerability. In this loop, the existence of the “CISA” custom field is checked. If the custom field for the vulnerability does not exist, the vulnerability ID is added to the
vulns_to_update array in line 320.
When the length of
vulns_to_update becomes 5000 or greater, all the vulnerabilities in:
vulns_to_update are updated with the CISA custom field with the “Bulk Update Vulnerabilities” API. If there are any vulnerabilities to be updated after running through the loops, a final vulnerability bulk update is invoked in line 329.
Bulk Vulnerabilities Update
The Bulk Update Vulnerabilities is used to set the “CISA” custom fields for the vulnerabilities that are associated with the CVE IDs from the CISA catalog to a “true” value. Remember that custom field values can only be strings or dates.
update_custom_field_id is composed only of the custom field ID.
Here is the output of the program:
This run took approximately 7.5 minutes. Each
. represents a search for vulnerabilities associated with a CISA CVE ID.
I hope this program helps with vulnerability risk management and provides you with a clear indication of which vulnerabilities are associated with the CISA catalog along with a risk score.
I would like to thank Jared Kalmus for his assistance and suggestions. As you may have noticed, most of the functions have been written with re-usability in mind. For example, check_for_custom_fields() has a custom field parameter instead of hardcoding “CISA” in the function. As always this code is in Kenna Security’s GitHub repository.
Until next time,