// fetchKEV.js import fs from 'fs'; import axios from 'axios'; import mysql from 'mysql2/promise'; const KEV_URL = 'https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json'; const DB = await mysql.createConnection({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, }); fs.writeFileSync('kev-sync.log', '', { flag: 'w' }); // 👈 Reset the log file cleanly function log(msg) { const now = new Date().toLocaleString('en-AU', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: true }).replace(/\b(AM|PM)\b/, m => m.toLowerCase()); const line = `[${now}] ${msg}`; console.log(line); fs.appendFileSync('kev-sync.log', `${line}\n`); } function safeDate(input) { return input ? new Date(input).toISOString().slice(0, 10) : null; } async function fetchAndInsertKEVs() { log('🚀 Starting KEV fetch from CISA...'); const { data } = await axios.get(KEV_URL); const vulns = data.vulnerabilities; let inserted = 0; for (const v of vulns) { try { await DB.execute(` INSERT INTO kev_catalog ( cve_id, vendor_project, product, vulnerability_name, date_added, short_description, required_action, due_date, known_ransomware_campaign_use, notes ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE date_added = VALUES(date_added), short_description = VALUES(short_description), required_action = VALUES(required_action), due_date = VALUES(due_date), known_ransomware_campaign_use = VALUES(known_ransomware_campaign_use), notes = VALUES(notes) `, [ v.cveID, v.vendorProject, v.product, v.vulnerabilityName, safeDate(v.dateAdded), v.shortDescription, v.requiredAction, safeDate(v.dueDate), v.knownRansomwareCampaignUse ?? null, v.notes ?? null ]); inserted++; } catch (err) { log(`❌ Failed to insert ${v.cveID}: ${err.message}`); } } log(`✅ Finished KEV sync. Inserted/updated: ${inserted}`); await DB.end(); } fetchAndInsertKEVs().catch(err => { log(`❌ Uncaught error: ${err.message}`); DB.end(); });