|
|
@@ -0,0 +1,132 @@ |
|
|
|
/* |
|
|
|
* SonarQube |
|
|
|
* Copyright (C) 2009-2022 SonarSource SA |
|
|
|
* mailto:info AT sonarsource DOT com |
|
|
|
* |
|
|
|
* This program is free software; you can redistribute it and/or |
|
|
|
* modify it under the terms of the GNU Lesser General Public |
|
|
|
* License as published by the Free Software Foundation; either |
|
|
|
* version 3 of the License, or (at your option) any later version. |
|
|
|
* |
|
|
|
* This program is distributed in the hope that it will be useful, |
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
|
|
* Lesser General Public License for more details. |
|
|
|
* |
|
|
|
* You should have received a copy of the GNU Lesser General Public License |
|
|
|
* along with this program; if not, write to the Free Software Foundation, |
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
|
|
*/ |
|
|
|
/* eslint-disable no-console */ |
|
|
|
|
|
|
|
/** |
|
|
|
* Execute this script by passing the path to the CWE XML definition file. |
|
|
|
* |
|
|
|
* You can download the full CWE database in XML format here: https://cwe.mitre.org/data/downloads.html |
|
|
|
* Make sure to unzip the downloaded file first before passing it to this script. |
|
|
|
* |
|
|
|
* Usage: |
|
|
|
* node scripts/update-cwes.js PATH |
|
|
|
* or: |
|
|
|
* yarn update-cwes PATH |
|
|
|
* |
|
|
|
* Example: |
|
|
|
* node scripts/update-cwes.js ~/Downloads/cwec_v4.6.xml |
|
|
|
* or: |
|
|
|
* yarn update-cwes ~/Downloads/cwec_v4.6.xml |
|
|
|
*/ |
|
|
|
|
|
|
|
const fs = require('fs'); |
|
|
|
const chalk = require('chalk'); |
|
|
|
const jsdom = require('jsdom'); |
|
|
|
const { trim } = require('lodash'); |
|
|
|
const path = require('path'); |
|
|
|
|
|
|
|
const IGNORED_STATUSES = ['Deprecated']; |
|
|
|
const STANDARDS_JSON_FILE = path.join( |
|
|
|
__dirname, |
|
|
|
'..', |
|
|
|
'src', |
|
|
|
'main', |
|
|
|
'js', |
|
|
|
'helpers', |
|
|
|
'standards.json' |
|
|
|
); |
|
|
|
|
|
|
|
const xmlContent = readXMLContent(process.argv[2]); |
|
|
|
const newCWEs = getCWEs(xmlContent); |
|
|
|
writeToStandardsJson(newCWEs); |
|
|
|
|
|
|
|
function readXMLContent(xmlPath) { |
|
|
|
if (fs.existsSync(xmlPath)) { |
|
|
|
try { |
|
|
|
fs.accessSync(xmlPath, fs.constants.R_OK); |
|
|
|
return fs.readFileSync(xmlPath).toString(); |
|
|
|
} catch (e) { |
|
|
|
console.error(chalk.red(`No read access for XML file '${xmlPath}'`)); |
|
|
|
throw e; |
|
|
|
} |
|
|
|
} else { |
|
|
|
console.error(chalk.red(`Cannot find XML file '${xmlPath}'`)); |
|
|
|
throw Error(''); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function getCWEs(xml) { |
|
|
|
const document = new jsdom.JSDOM(xml); |
|
|
|
const weaknesses = document.window.document.querySelectorAll('Weaknesses Weakness'); |
|
|
|
const cwes = { |
|
|
|
unknown: { |
|
|
|
title: 'No CWE associated' |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
weaknesses.forEach(weakness => { |
|
|
|
const id = weakness.getAttribute('ID'); |
|
|
|
const title = weakness.getAttribute('Name'); |
|
|
|
const status = weakness.getAttribute('Status'); |
|
|
|
let description = ''; |
|
|
|
|
|
|
|
if (!id) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (IGNORED_STATUSES.includes(status)) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (!title) { |
|
|
|
console.log(chalk.yellow(`No Name attribute found for CWE '${id}'. Skipping.`)); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
const descriptionEl = weakness.querySelector('Description'); |
|
|
|
if (descriptionEl) { |
|
|
|
description = trim(descriptionEl.textContent); |
|
|
|
} |
|
|
|
|
|
|
|
cwes[id] = { title, description }; |
|
|
|
}); |
|
|
|
|
|
|
|
return cwes; |
|
|
|
} |
|
|
|
|
|
|
|
function writeToStandardsJson(cwes) { |
|
|
|
try { |
|
|
|
fs.accessSync(STANDARDS_JSON_FILE, fs.constants.W_OK); |
|
|
|
} catch (e) { |
|
|
|
console.error(chalk.red(`No write access for standards.json ('${STANDARDS_JSON_FILE}') file`)); |
|
|
|
throw e; |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
const json = JSON.parse(fs.readFileSync(STANDARDS_JSON_FILE).toString()); |
|
|
|
json.cwe = cwes; |
|
|
|
fs.writeFileSync(STANDARDS_JSON_FILE, JSON.stringify(json, undefined, 2)); |
|
|
|
} catch (e) { |
|
|
|
console.error( |
|
|
|
chalk.red(`Failed to write data to standards.json ('${STANDARDS_JSON_FILE}') file`) |
|
|
|
); |
|
|
|
throw e; |
|
|
|
} |
|
|
|
} |