🦆
【GAS】WindowsOSのバージョンとCVE情報を紐づけてみる(途中)
なぜ作成したのか
- 昨日macOSで実装した機能をWindows側でも実装してみようという試み
技術スタック
- Google Spreadsheet
- GAS
- MSRC-Microsoft-Security-Updates-API
- NVD CVE API
やりたいこと
- MSRCのAPIからWindowsOSのバージョン情報、関連CVE番号の情報を取得する
- 登場するCVE番号についてNVDのAPIで詳細情報を取得する
- AppsheetでOSバージョンとCVE情報を紐づけて見えるようにする
GAS(作成中)
- APIを試し打ちしていて気が付いたが、あるAPIは値をJSON形式で返却するものの、あるAPIはXML形式で返却するという謎な仕様
// スクリプトプロパティからスプレッドシートIDを取得
const SPREADSHEET_ID = PropertiesService.getScriptProperties().getProperty('SPREADSHEET_ID');
const MSRC_API_UPDATES_URL = 'https://api.msrc.microsoft.com/cvrf/v3.0/updates/';
function main() {
// Updateリストを取得
const updateData = fetchMsrcUpdateData();
const spreadsheet = SpreadsheetApp.openById(SPREADSHEET_ID);
updateWindowsVersionSheet(spreadsheet, updateData);
// updateWindowsVersionSheet(spreadsheet, data);
// updateWindowsVersionCVEsSheet(spreadsheet, data);
// updateWindowsExploitedCVEsSheet(spreadsheet, data);
// updateWorkCVEsSheet(spreadsheet, data);
// updateCVEsSheet(spreadsheet);
}
function fetchMsrcUpdateData() {
// 返り値はJSON形式
const response = UrlFetchApp.fetch(MSRC_API_UPDATES_URL);
return JSON.parse(response.getContentText());
}
function updateWindowsVersionSheet(spreadsheet, data) {
const sheet = getOrCreateSheet(spreadsheet, 'WindowsVersion');
sheet.clear();
sheet.appendRow(['ID', 'Alias', 'DocumentTitle', 'Severity','InitialReleaseDate','CurrentReleaseDate', 'CvrfUrl']);
const cveSheet = getOrCreateSheet(spreadsheet, 'WindowsVersion-CVEs');
cveSheet.clear();
cveSheet.appendRow(['id', 'CVE', 'ProductID']);
const productSheet = getOrCreateSheet(spreadsheet, 'WindowsProduct');
productSheet.clear();
productSheet.appendRow(['ProductID', 'FullProductName']);
data.value.forEach(entry => {
sheet.appendRow([
entry.ID || '',
entry.Alias || '',
entry.DocumentTitle || '',
entry.Severity || '',
entry.InitialReleaseDate || '',
entry.CurrentReleaseDate || '',
entry.CvrfUrl || ''
]);
if(entry.CvrfUrl){
// 返り値はXML形式
const urlResponse = UrlFetchApp.fetch(entry.CvrfUrl);
var xmlDoc = XmlService.parse(urlResponse.getContentText());
var rootDoc = xmlDoc.getRootElement();
updateWindowsVersionCVEsSheet(cveSheet,rootDoc,entry.ID);
}
});
}
function updateWindowsVersionCVEsSheet(sheet, data, id) {
var ns = XmlService.getNamespace("vuln", "http://www.icasi.org/CVRF/schema/vuln/1.1");
var vulnerabilitys = data.getChildren("Vulnerability",ns);
vulnerabilitys.forEach(entry => {
var cve = entry.getChildren("CVE",ns)[0].getValue();
var productIDs = entry.getChildren("ProductStatuses",ns)[0].getChildren("Status",ns)[0].getChildren("ProductID",ns);
productIDs.forEach(pdata => {
sheet.appendRow([
id,
cve,
pdata.getValue()
])
});
}) ;
}
function updateWindowsProductSheet(sheet, data) {
(実装中)
}
function updateWindowsExploitedCVEsSheet(spreadsheet, data) {
(実装中)
}
function updateWorkWinCVEsSheet(spreadsheet, url) {
(実装中)
}
function updateCVEsSheet(spreadsheet) {
(実装中)
}
function getOrCreateSheet(spreadsheet, sheetName) {
const sheet = spreadsheet.getSheetByName(sheetName);
return sheet || spreadsheet.insertSheet(sheetName);
}
所感
- XMLの罠に引っかかったため停滞中。もちろんJSON前提で実装してきたChatGPTくんには注意してみたものの、いい感じに改善されないので自前で実装してる
- XMLの読みとき頑張る
Discussion