Skip to content

Commit

Permalink
Fix: Handle missing primary CVSS metrics in CVEs
Browse files Browse the repository at this point in the history
Updating CVEs from JSON now handles the case where there are no
primary metrics for the newest CVSS version by also checking
metrics of other CVSS version or falling back to the secondary metrics
of the newest CVSS version.

This fixes a crash when loading a JSON feed containing CVEs with no
primary metrics for the newest CVSS version.
  • Loading branch information
timopollmeier committed Dec 11, 2024
1 parent 61e9921 commit cd3e76b
Showing 1 changed file with 52 additions and 47 deletions.
99 changes: 52 additions & 47 deletions src/manage_sql_secinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -3577,7 +3577,8 @@ handle_json_cve_item (cJSON *item)
modified_time = parse_iso_time (modified);

cJSON *metrics_json;
cJSON *cvss_metric_array;
cJSON *best_cvss_metric_item = NULL;
gboolean cvss_metric_is_primary = FALSE;

metrics_json = cJSON_GetObjectItemCaseSensitive (cve_json, "metrics");
if (!cJSON_IsObject (metrics_json))
Expand All @@ -3587,73 +3588,77 @@ handle_json_cve_item (cJSON *item)
return -1;
}

gboolean cvss_metric_found = FALSE;

const char *cvss_metric_keys[] = {
"cvssMetricV40",
"cvssMetricV31",
"cvssMetricV30",
"cvssMetricV2"};

score_dbl = SEVERITY_MISSING;
vector = NULL;

for (int i = 0; i < 4; i++)
{
cvss_metric_array
cJSON *cvss_metric_array
= cJSON_GetObjectItemCaseSensitive (metrics_json, cvss_metric_keys[i]);
if (cJSON_IsArray (cvss_metric_array)
&& cJSON_GetArraySize (cvss_metric_array) > 0)
{
cvss_metric_found = TRUE;
break;
cJSON *cvss_metric_item;
cJSON_ArrayForEach (cvss_metric_item, cvss_metric_array)
{
char *source_type
= json_object_item_string (cvss_metric_item, "type");
if (source_type == NULL)
{
g_warning ("%s: type missing in CVSS metric for %s.",
__func__, cve_id);
return -1;
}
if (strcmp (source_type, "Primary") == 0)
cvss_metric_is_primary = TRUE;

if (cvss_metric_is_primary)
{
best_cvss_metric_item = cvss_metric_item;
break;
}
else if (best_cvss_metric_item == NULL)
best_cvss_metric_item = cvss_metric_item;
}

if (cvss_metric_is_primary)
break;
}
}

if (cvss_metric_found)
if (best_cvss_metric_item)
{
cJSON *cvss_json;
cJSON *cvss_metric_item;
char *source_type;
cJSON *cvss_json
= cJSON_GetObjectItemCaseSensitive (best_cvss_metric_item, "cvssData");
if (!cJSON_IsObject (cvss_json))
{
g_warning ("%s: cvssData missing or not an object for %s.",
__func__, cve_id);
return -1;
}

cJSON_ArrayForEach (cvss_metric_item, cvss_metric_array)
score_dbl = json_object_item_double (cvss_json,
"baseScore",
SEVERITY_MISSING);
if (score_dbl == SEVERITY_MISSING)
{
source_type = json_object_item_string (cvss_metric_item, "type");
if (source_type == NULL)
{
g_warning ("%s: type missing in CVSS metric for %s.",
__func__, cve_id);
return -1;
}
else if (strcmp (source_type, "Primary"))
continue;
g_warning ("%s: baseScore missing for %s.", __func__, cve_id);
return -1;
}

cvss_json = cJSON_GetObjectItemCaseSensitive (cvss_metric_item,
"cvssData");
if (!cJSON_IsObject (cvss_json))
{
g_warning ("%s: cvssData missing or not an object for %s.",
__func__, cve_id);
return -1;
}
score_dbl = json_object_item_double (cvss_json,
"baseScore",
SEVERITY_MISSING);
if (score_dbl == SEVERITY_MISSING)
{
g_warning ("%s: baseScore missing for %s.", __func__, cve_id);
return -1;
}
vector = json_object_item_string (cvss_json, "vectorString");
if (vector == NULL)
{
g_warning ("%s: vectorString missing for %s.", __func__, cve_id);
return -1;
}
vector = json_object_item_string (cvss_json, "vectorString");
if (vector == NULL)
{
g_warning ("%s: vectorString missing for %s.", __func__, cve_id);
return -1;
}
}
else
{
score_dbl = SEVERITY_MISSING;
vector = NULL;
}

cJSON *descriptions_json;
cJSON *description_item_json;
Expand Down

0 comments on commit cd3e76b

Please sign in to comment.