dce-dev-wizard
Version:
Wizard for managing development apps at Harvard DCE.
192 lines • 8.19 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
// Import libs
const clear_1 = __importDefault(require("clear"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const papaparse_1 = __importDefault(require("papaparse"));
// Import helpers
const print_1 = __importDefault(require("../helpers/print"));
const prompt_1 = __importDefault(require("../helpers/prompt"));
const showChooser_1 = __importDefault(require("../helpers/showChooser"));
const scrapeCVE_1 = __importDefault(require("../helpers/scrapeCVE"));
const WizSeverity_1 = __importDefault(require("../types/WizSeverity"));
// Get project directory
const currDir = (_a = (process.env.PWD || process.env.CWD)) !== null && _a !== void 0 ? _a : __dirname;
/**
* Review current CVEs (from Wiz CSV) and decide how to handle each one
* @author Allison Zhang
* @author Gabe Abrams
*/
const reviewCVEs = () => __awaiter(void 0, void 0, void 0, function* () {
// Clear the screen and show title
(0, clear_1.default)();
print_1.default.title('Import Wiz CSV');
console.log('\nFind the desired Wiz Report CSV in your directory and drag/drop it into this window.\n');
// Get the file path
const wizReportPath = (0, prompt_1.default)('> ', true).replace(/['"]/g, '').trim();
// Read in the trivy results
if (!fs_1.default.existsSync(wizReportPath)) {
(0, clear_1.default)();
print_1.default.title('Error [File Not Found]');
console.error(`\nFile not found: ${wizReportPath}\n`);
print_1.default.enterToContinue();
return;
}
// Convert to object
let wizResults;
try {
wizResults = papaparse_1.default.parse(fs_1.default.readFileSync(wizReportPath, 'utf8'), {
header: true,
skipEmptyLines: true,
delimitersToGuess: [',', ';', '\t'],
dynamicTyping: true,
});
}
catch (error) {
(0, clear_1.default)();
print_1.default.title('Error [CSV Invalid]');
console.error(`\nError parsing CSV file: ${error}\n`);
print_1.default.enterToContinue();
return;
}
// Make sure that the schema is correct
if (!wizResults || !wizResults.data) {
(0, clear_1.default)();
print_1.default.title('Error [Invalid Wiz Report]');
console.error('\nWiz results should use \',\', \';\', and \'\\t\'. Please provide a Wiz scan CSV file.\n');
print_1.default.enterToContinue();
return;
}
let wizRows = [];
for (const row of wizResults.data) {
let wizRow = {
wizURL: row.WizURL,
cve: row.Name,
severity: WizSeverity_1.default.Low,
remediation: row.Remediation,
locationPath: row.LocationPath,
package: row.DetailedName,
version: row.Version,
fixedVersion: row.FixedVersion,
advisoryLink: row.Link,
awsAccount: row.SubscriptionName,
};
switch (row.Severity) {
case 'Critical':
wizRow.severity = WizSeverity_1.default.Critical;
break;
case 'High':
wizRow.severity = WizSeverity_1.default.High;
break;
case 'Medium':
wizRow.severity = WizSeverity_1.default.Medium;
break;
case 'Low':
wizRow.severity = WizSeverity_1.default.Low;
break;
default:
wizRow.severity = WizSeverity_1.default.Low;
}
;
wizRows.push(wizRow);
}
;
// List of explanations for reviewed CVEs
const reviewedCVEs = [];
// If no vulnerabilities, exit
if (!wizRows || wizRows.length === 0) {
(0, clear_1.default)();
print_1.default.title('Success!');
console.log('\nNo vulnerabilities found! 🎉\n');
print_1.default.enterToContinue();
return;
}
else {
// Loop through vulnerabilities
for (let i = 0; i < wizRows.length; i++) {
(0, clear_1.default)();
let information;
try {
information = yield (0, scrapeCVE_1.default)(wizRows[i].advisoryLink);
}
catch (error) {
console.error(`Error scraping CVE information: ${error}`);
information = { title: 'Unknown', description: 'Unknown' };
}
print_1.default.title(`Severity: ${wizRows[i].severity} | Vulnerability ${i + 1} of ${wizRows.length}`);
console.log(`CVE: ${wizRows[i].cve}\n`);
console.log(`Title: ${information.title}\n`);
console.log(`Description: ${information.description}\n`);
console.log(`Version (Installed): ${wizRows[i].version}`);
console.log(`Version (Fixed): ${wizRows[i].fixedVersion}`);
console.log(`Primary URL: ${wizRows[i].wizURL}`);
console.log(`Advisory Link: ${wizRows[i].advisoryLink}\n`);
console.log(`Remediation:\n${wizRows[i].remediation}\n`);
console.log(`Location Path: ${wizRows[i].locationPath}\n`);
console.log(`AWS Account: ${wizRows[i].awsAccount}\n`);
// Ask user what to do with this vulnerability
const vulnerabilityOptions = (0, showChooser_1.default)({
question: 'Review Vulnerability:',
options: [
{
description: 'Reviewed (Not a problem)',
tag: 'R',
},
{
description: 'Snooze (Will fix later)',
tag: 'S',
},
],
dontClear: true,
});
// If reviewing, ask for explanation, then add to reviewed CVEs list
if (vulnerabilityOptions.tag === 'R') {
console.log('\nPlease explain why this vulnerability can be ignored.');
console.log('Explanation: ');
let explanation = (0, prompt_1.default)('', true).trim();
while (!explanation || explanation.length === 0) {
console.log('Please provide an explanation: ');
explanation = (0, prompt_1.default)('', true);
}
reviewedCVEs.push({
cve: wizRows[i].cve,
title: information.title,
explanation: explanation,
});
}
// If snoozing, just continue
}
}
// Write to .reviewed-cves file
const reviewedCVEsPath = path_1.default.join(currDir, '.reviewed-cves');
// Append all reviewed CVEs to the file
let reviewedCVEsContent = '';
reviewedCVEs.forEach((cve) => {
reviewedCVEsContent += `\n# ${cve.title}\n# Note: ${cve.explanation}\n`;
});
try {
fs_1.default.appendFileSync(reviewedCVEsPath, reviewedCVEsContent);
}
catch (error) {
print_1.default.title('Error [File Append]');
console.error(`\nError appending reviewed CVEs to ${reviewedCVEsPath}: ${error}\n`);
print_1.default.enterToContinue();
return;
}
});
exports.default = reviewCVEs;
//# sourceMappingURL=reviewCVEs.js.map