Skip to content

Instantly share code, notes, and snippets.

@greggles
Created December 16, 2024 16:40
Show Gist options
  • Save greggles/e3c525af1790c05b1ff882eee826f0fd to your computer and use it in GitHub Desktop.
Save greggles/e3c525af1790c05b1ff882eee826f0fd to your computer and use it in GitHub Desktop.
<?php
// A standalone script to generate CVE json from Drupal.org's API.
// The intended output requires manual involvement at this point.
// usage: php advisory-to-cvejson.php
// Function to fetch JSON data from a URL
function fetch_json_data($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
// Function split composer range to cve style data.
function split_drupal_composer_range($range) {
if (empty($range)) {
// This happens mostly for 7.x only vulnerabilities.
$version_range_json[] = [
'lessThan' => '7.x',
'status' => 'affected',
'version' => '7.x',
'versionType' => 'semver'
];
}
elseif ($range == '*') {
// For unsupported things that are never fixed, indicate everything is vulnerable.
$version_range_json[] = [
'lessThan' => '',
'status' => 'affected',
'version' => '*.*',
'versionType' => 'semver'
];
}
else {
// Assumes the first version is always >= and the second is always <.
// Assumes multiple values are split on ||.
$range = trim($range);
$version_range_json = [];
$version_strings = explode('||', $range);
foreach ($version_strings as $version_string) {
$version_string = str_replace(['<', '=', '>'], '', $version_string);
$version_string = trim($version_string);
$versions = preg_split('/\s+/', $version_string);
$vulnerable_version = trim($versions[0]);
// When this is empty it means only one version was specified.
if (empty($versions[1])) {
$min_fixed_version = $vulnerable_version;
$vulnerable_version = '0.0.0';
}
else {
$min_fixed_version = $versions[1];
}
$version_range_json[] = [
'lessThan' => trim($min_fixed_version),
'status' => 'affected',
'version' => $vulnerable_version,
'versionType' => 'semver'
];
}
}
return $version_range_json;
}
function parse_list_names($html_string) {
$names = [];
$dom = new DOMDocument();
@$dom->loadHTML($html_string); // Suppress potential warnings
$list = $dom->getElementsByTagName('ul')->item(0);
if ($list) {
$list_elements = $list->getElementsByTagName('li');
foreach ($list_elements as $list_item) {
$anchor = $list_item->getElementsByTagName('a')->item(0);
if ($anchor) {
$names[] = $anchor->textContent;
}
}
}
return $names;
}
function build_credit_values($credit_field, $credit_type) {
$return = [];
if (!empty($credit_field)) {
// Credit types are finder, 'remediation developer', 'coordinator'.
$names = parse_list_names($credit_field['value']);
foreach ($names as $name) {
$return[] = [
'lang' => 'en',
'type' => $credit_type,
'value' => $name
];
}
}
return $return;
}
function get_cwe_capec_from_advisory_url($advisory_url) {
$advisories = [
'https://www.drupal.org/sa-contrib-2024-076' => ['CWE' => '862', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Missing Authorization'],
'https://www.drupal.org/sa-contrib-2024-075' => ['CWE' => '862', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Missing Authorization'],
'https://www.drupal.org/sa-contrib-2024-074' => ['CWE' => '862', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Missing Authorization'],
'https://www.drupal.org/sa-contrib-2024-073' => ['CWE' => '287', 'CAPEC' => '180', 'CAPEC-DESC' => 'Exploiting Incorrectly Configured Access Control Security Levels', 'CWE-DESC' => 'Improper Authentication'],
'https://www.drupal.org/sa-contrib-2024-072' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-071' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-070' => ['CWE' => '352', 'CAPEC' => '62', 'CAPEC-DESC' => 'Cross Site Request Forgery', 'CWE-DESC' => 'Cross-Site Request Forgery (CSRF)'],
'https://www.drupal.org/sa-contrib-2024-069' => ['CWE' => '862', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Missing Authorization'],
'https://www.drupal.org/sa-contrib-2024-068' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-067' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-066' => ['CWE' => '862', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Missing Authorization'],
'https://www.drupal.org/sa-contrib-2024-065' => ['CWE' => '862', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Missing Authorization'],
'https://www.drupal.org/sa-contrib-2024-064' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-063' => ['CWE' => '502', 'CAPEC' => '586', 'CAPEC-DESC' => 'Object Injection', 'CWE-DESC' => 'Deserialization of Untrusted Data'],
'https://www.drupal.org/sa-contrib-2024-062' => ['CWE' => '502', 'CAPEC' => '586', 'CAPEC-DESC' => 'Object Injection', 'CWE-DESC' => 'Deserialization of Untrusted Data'],
'https://www.drupal.org/sa-contrib-2024-061' => ['CWE' => '502', 'CAPEC' => '586', 'CAPEC-DESC' => 'Object Injection', 'CWE-DESC' => 'Deserialization of Untrusted Data'],
'https://www.drupal.org/sa-contrib-2024-060' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-059' => ['CWE' => '352', 'CAPEC' => '62', 'CAPEC-DESC' => 'Cross Site Request Forgery', 'CWE-DESC' => 'Cross-Site Request Forgery (CSRF)'],
'https://www.drupal.org/sa-contrib-2024-058' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-057' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-056' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-055' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-052' => ['CWE' => '502', 'CAPEC' => '586', 'CAPEC-DESC' => 'Object Injection', 'CWE-DESC' => 'Deserialization of Untrusted Data'],
'https://www.drupal.org/sa-contrib-2024-051' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-050' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-049' => ['CWE' => '78', 'CAPEC' => '88', 'CAPEC-DESC' => 'OS Command Injection', 'CWE-DESC' => 'Improper Neutralization of Special Elements used in an OS Command (\'OS Command Injection\')'],
'https://www.drupal.org/sa-contrib-2024-048' => ['CWE' => '352', 'CAPEC' => '62', 'CAPEC-DESC' => 'Cross Site Request Forgery', 'CWE-DESC' => 'Cross-Site Request Forgery (CSRF)'],
'https://www.drupal.org/sa-contrib-2024-047' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-046' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-045' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-044' => ['CWE' => '613', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Insufficient Session Expiration'],
'https://www.drupal.org/sa-contrib-2024-043' => ['CWE' => '384', 'CAPEC' => '61', 'CAPEC-DESC' => 'Session Fixation', 'CWE-DESC' => 'Session Fixation'],
'https://www.drupal.org/sa-contrib-2024-042' => ['CWE' => '863', 'CAPEC' => '212', 'CAPEC-DESC' => 'Functionality Misuse', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-041' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-040' => ['CWE' => '201', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Insertion of Sensitive Information Into Sent Data'],
'https://www.drupal.org/sa-contrib-2024-039' => ['CWE' => '843', 'CAPEC' => '469', 'CAPEC-DESC' => 'HTTP DoS', 'CWE-DESC' => 'Access of Resource Using Incompatible Type (\'Type Confusion\')'],
'https://www.drupal.org/sa-contrib-2024-038' => ['CWE' => '799', 'CAPEC' => '212', 'CAPEC-DESC' => 'Functionality Misuse', 'CWE-DESC' => 'Improper Control of Interaction Frequency'],
'https://www.drupal.org/sa-contrib-2024-037' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-036' => ['CWE' => '1220', 'CAPEC' => '148', 'CAPEC-DESC' => 'Content Spoofing', 'CWE-DESC' => 'Insufficient Granularity of Access Control'],
'https://www.drupal.org/sa-contrib-2024-035' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-034' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-033' => ['CWE' => '201', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Insertion of Sensitive Information Into Sent Data'],
'https://www.drupal.org/sa-contrib-2024-032' => ['CWE' => '96', 'CAPEC' => '252', 'CAPEC-DESC' => 'PHP Local File Inclusion', 'CWE-DESC' => 'Improper Neutralization of Directives in Statically Saved Code (\'Static Code Injection\')'],
'https://www.drupal.org/sa-contrib-2024-031' => ['CWE' => '96', 'CAPEC' => '252', 'CAPEC-DESC' => 'PHP Local File Inclusion', 'CWE-DESC' => 'Improper Neutralization of Directives in Statically Saved Code (\'Static Code Injection\')'],
'https://www.drupal.org/sa-contrib-2024-030' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-029' => ['CWE' => '96', 'CAPEC' => '252', 'CAPEC-DESC' => 'PHP Local File Inclusion', 'CWE-DESC' => 'Improper Neutralization of Directives in Statically Saved Code (\'Static Code Injection\')'],
'https://www.drupal.org/sa-contrib-2024-028' => ['CWE' => '96', 'CAPEC' => '252', 'CAPEC-DESC' => 'PHP Local File Inclusion', 'CWE-DESC' => 'Improper Neutralization of Directives in Statically Saved Code (\'Static Code Injection\')'],
'https://www.drupal.org/sa-contrib-2024-027' => ['CWE' => '96', 'CAPEC' => '252', 'CAPEC-DESC' => 'PHP Local File Inclusion', 'CWE-DESC' => 'Improper Neutralization of Directives in Statically Saved Code (\'Static Code Injection\')'],
'https://www.drupal.org/sa-contrib-2024-026' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-025' => ['CWE' => '352', 'CAPEC' => '62', 'CAPEC-DESC' => 'Cross Site Request Forgery', 'CWE-DESC' => 'Cross-Site Request Forgery (CSRF)'],
'https://www.drupal.org/sa-contrib-2024-024' => ['CWE' => '352', 'CAPEC' => '62', 'CAPEC-DESC' => 'Cross Site Request Forgery', 'CWE-DESC' => 'Cross-Site Request Forgery (CSRF)'],
'https://www.drupal.org/sa-contrib-2024-023' => ['CWE' => '201', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Insertion of Sensitive Information Into Sent Data'],
'https://www.drupal.org/sa-contrib-2024-022' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-021' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-020' => ['CWE' => '1220', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Insufficient Granularity of Access Control'],
'https://www.drupal.org/sa-contrib-2024-019' => ['CWE' => '202', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Exposure of Sensitive Information Through Data Queries'],
'https://www.drupal.org/sa-contrib-2024-018' => ['CWE' => '201', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Insertion of Sensitive Information Into Sent Data'],
'https://www.drupal.org/sa-contrib-2024-017' => ['CWE' => '863', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Incorrect Authorization'],
'https://www.drupal.org/sa-contrib-2024-016' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-015' => ['CWE' => '266', 'CAPEC' => '233', 'CAPEC-DESC' => 'Privilege Escalation', 'CWE-DESC' => 'Incorrect Privilege Assignment'],
'https://www.drupal.org/sa-contrib-2024-014' => ['CWE' => '352', 'CAPEC' => '62', 'CAPEC-DESC' => 'Cross Site Request Forgery', 'CWE-DESC' => 'Cross-Site Request Forgery (CSRF)'],
'https://www.drupal.org/sa-contrib-2024-013' => ['CWE' => '282', 'CAPEC' => '425', 'CAPEC-DESC' => 'Target Influence via Framing', 'CWE-DESC' => 'Improper Ownership Management'],
'https://www.drupal.org/sa-contrib-2024-012' => ['CWE' => '266', 'CAPEC' => '425', 'CAPEC-DESC' => 'Target Influence via Framing', 'CWE-DESC' => 'Incorrect Privilege Assignment'],
'https://www.drupal.org/sa-contrib-2024-011' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-010' => ['CWE' => '282', 'CAPEC' => '425', 'CAPEC-DESC' => 'Target Influence via Framing', 'CWE-DESC' => 'Improper Ownership Management'],
'https://www.drupal.org/sa-contrib-2024-009' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-008' => ['CWE' => '352', 'CAPEC' => '62', 'CAPEC-DESC' => 'Cross Site Request Forgery', 'CWE-DESC' => 'Cross-Site Request Forgery (CSRF)'],
'https://www.drupal.org/sa-contrib-2024-007' => ['CWE' => '862', 'CAPEC' => '87', 'CAPEC-DESC' => 'Forceful Browsing', 'CWE-DESC' => 'Missing Authorization'],
'https://www.drupal.org/sa-contrib-2024-006' => ['CWE' => '749', 'CAPEC' => '154', 'CAPEC-DESC' => 'Resource Location Spoofing', 'CWE-DESC' => 'Exposed Dangerous Method or Function'],
'https://www.drupal.org/sa-contrib-2024-005' => ['CWE' => '285', 'CAPEC' => '150', 'CAPEC-DESC' => 'Collect Data from Common Resource Locations', 'CWE-DESC' => 'Improper Authorization'],
'https://www.drupal.org/sa-contrib-2024-004' => ['CWE' => '284', 'CAPEC' => '150', 'CAPEC-DESC' => 'Collect Data from Common Resource Locations', 'CWE-DESC' => 'Improper Access Control'],
'https://www.drupal.org/sa-contrib-2024-003' => ['CWE' => '1390', 'CAPEC' => '114', 'CAPEC-DESC' => 'Authentication Abuse', 'CWE-DESC' => 'Weak Authentication'],
'https://www.drupal.org/sa-contrib-2024-002' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
'https://www.drupal.org/sa-contrib-2024-001' => ['CWE' => '79', 'CAPEC' => '63', 'CAPEC-DESC' => 'Cross-Site Scripting (XSS)', 'CWE-DESC' => 'Improper Neutralization of Input During Web Page Generation (\'Cross-site Scripting\')'],
];
$item = $advisories[$advisory_url];
$cwe = [
'cweId' => 'CWE-'. $item['CWE'],
'description' => 'CWE-'. $item['CWE'] .' '. $item['CWE-DESC'],
'lang' => 'en',
'type' => 'CWE',
];
$capec['capecId'] = 'CAPEC-'. $item['CAPEC'];
$capec['descriptions'][] = [
'lang' => 'en',
'value' => 'CAPEC-'. $item['CAPEC'] .' '. $item['CAPEC-DESC'],
];
return ['cwe' => $cwe, 'capec' => $capec];
}
// URL of the JSON data.
$url = 'https://www.drupal.org/api-d7/node.json?type=sa&sort=created&direction=DESC&limit=50&page=0';
$url = 'https://www.drupal.org/api-d7/node.json?type=sa&sort=created&direction=DESC&limit=50&page=1';
// Fetch the JSON data.
$jsonData = fetch_json_data($url);
// Check if the 'list' key exists and if it's an array.
if (isset($jsonData['list']) && is_array($jsonData['list'])) {
// Loop over each item in the 'list' array.
foreach ($jsonData['list'] as $item) {
// Skip if its core or a PSA.
if ($item['field_project']['id'] == 3060 or !empty($item['field_is_psa'])) {
error_log('Skipping core and PSAs: '. $item['url']);
continue;
}
// Skip if its an advisory that had its own CVE upstream.
if (in_array($item['url'], ['https://www.drupal.org/sa-contrib-2024-054', 'https://www.drupal.org/sa-contrib-2024-053'])) {
error_log('Skipping because its got its own cve: '. $item['url']);
continue;
}
// Skip those created before 2024. This is created+1 for https://www.drupal.org/sa-contrib-2023-055
if ($item['created'] < 1703091772) {
error_log('Skipping because its too old: '. $item['url']);
continue;
}
// Give d.o a second between request thats made below.
sleep(1);
$cve_data = $cve = $affected = $credits = [];
$cve = ['dataType' => 'CVE_RECORD', 'dataVersion' => 5.1];
// Extract and reformat values from the current item.
$cve_data['title'] = $item['title'];
$advisory_id = substr($cve_data['title'], -19);
error_log("Starting parsing for: ". $item['url']);
$cve['cveMetadata'] = ['cveId' => $advisory_id];
$dt = DateTime::createFromFormat('U', $item['created']);
// TODO: properly get Z time in PHP like 2024-11-21T03:23:00.000Z.
$cve_data['datePublic'] = $dt->format("Y-m-d\TH:i:s.000\Z");
$cve_data['references'][]['url'] = $item['url'];
// CWE and CAPEC.
$problem_data = get_cwe_capec_from_advisory_url($item['url']);
$cve_data['problemTypes'][]['descriptions'][] = $problem_data['cwe'];
$cve_data['impacts'][] = $problem_data['capec'];
// Get project information.
$project = fetch_json_data('https://www.drupal.org/api-d7/node.json?nid=' . $item['field_project']['id']);
$affected['collectionURL'] = "https://www.drupal.org/project/" . $project['list'][0]['field_project_machine_name'];
$affected['product'] = $project['list'][0]['title'];
$affected['vendor'] = 'Drupal';
$affected['repo'] = "https://git.drupalcode.org/project/" . $project['list'][0]['field_project_machine_name'];
$affected['versions'] = split_drupal_composer_range($item['field_affected_versions']);
$cve_data['affected'][] = $affected;
// Get credits.
$finders = build_credit_values($item['field_sa_reported_by'], 'finder');
$remediation_developers = build_credit_values($item['field_sa_fixed_by'], 'remediation developer');
$coordinators = build_credit_values($item['field_sa_coordinated_by'], 'coordinator');
$cve_data['credits'] = array_merge($finders, $remediation_developers, $coordinators);
// Put cve data in the proper nested spot on the main cve.
$cve['containers']['cna'] = $cve_data;
file_put_contents($advisory_id . '.json', json_encode($cve));
error_log("Creating the file for: ". $advisory_id);
}
} else {
echo "Error: 'list' key not found or is not an array.\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment