SaaS型Webアプリ診断ツール「AeyeScan」を運営している株式会社エーアイセキュリティラボによる、セキュリティテストの自動化、脆弱性診断の内製化、AI/機械学習などの技術情報の共有を目的とした記事です。
AeyeScanの情報はこちら https://www.aeyescan.jp
エーアイセキュリティラボの情報はこちら https://www.aeyesec.jp
こんにちは!株式会社エーアイセキュリティラボ カスタマーサクセス担当 日髙です。
今回は、Google Apps Script(GAS)を使って、AeyeScanの通知メールからスキャン再開のAPIを自動で実行する仕組みを作成していきます。
目次
概要
実現するもの
APIキーの作成と設定
ステップ1(事前の時刻取得)
ステップ2(メールの受信API)
ステップ3(メールの解析)
ステップ4(再スキャンの実行)
検証
利用上の注意
おわりに
参考文献
概要
脆弱性診断ツールを利用していると、診断対象によっては、一時的にサイトからの応答が遅くなり、スキャンができない状態となることがあります。そういった場合、AeyeScanでは、メールや各種チャットツール等に通知が行われます。
今回は、このメール通知機能とAeyeScanのAPIを活用して、自動でスキャンの再開を行う仕組みを作成します。
実現するもの
今回は、GmailでAeyeScanの通知メール(スキャン停止時に送られる)を取得し、受信から5分以上経過していたら、スキャンを再開するAPIを実行するGASのスクリプトを作成します。
それでは早速作っていきましょう!
APIキーの作成と設定
事前にAeyeScanのAPIを実行するため、APIキーを発行します。
APIキーはAeyeScanのメニューバーの「アカウント管理」→「APIキー管理」から作成できます。
APIキーを作成する際には書き込み・実行権限を「あり」に設定します。
作成したAPIキーとトークンは後から確認できないため、安全な場所に保管してください。
今回作成するスクリプトは以下から閲覧可能です。
(ご自身のgoogleアカウントへのログインが必要です。)
https://script.google.com/d/15O3VKy7sZ5cWOEvRAgs2wjPU04eh7eSP4ZbprrsK9eSpLZw4J1H5ur6m/edit?usp=share_link
以降スクリプトの詳細についてステップ1~4に分けて解説していきます。
ステップ1(事前の時刻取得)
まずは、スクリプトの中で使用する時間を事前に取得しておきます。
今回は、5分おきにメールボックスを確認して、直近10分に届いたメールを取得し、メールの受信から5分以上経過していたら
スキャンの再開を実行します。
そのため、現在時刻から10分前と5分前の時間(ミリ秒)を取得しておきます。
//10分前のUNIXタイム(ミリ秒)を取得
const date = new Date(); // 現在日時を取得
const now = date.getTime();
const before10Time = now - (1000 * 60 * 10); // 10分前
const before5Time = now - (1000 * 60 * 5); // 5分前
ステップ2(メールの受信API)
次にGmailを取得する処理です。
Gmailの検索を行うには、GmailAppのsearchメソッドを利用します。
また、AeyeScanの通知メールは、「no-reply@aeyescan.com」という宛先から届くので、
「10分前」+「no-reply@aeyescan.comからのメール」という条件でメールを取得します。
※メールの検索条件の「10分前」を指定するためミリ秒から秒に変換する必要があります。
//メール取得処理(直近10分)
const before10Sec = Math.floor(before10Time / 1000); // ミリ秒を秒に変換
//取得条件(10分前から現在で届いた、AeyeScanからのメールのスレッドを取得)
const query = 'after:' + before10Sec.toString() + ' ' + 'From:no-reply@aeyescan.com';
var threads = GmailApp.search(query);
ステップ3(メールの解析)
次に、受信したメールの中から、「サイトから応答がなく、スキャン停止した場合に送信されるメール」が存在するかを確認します。
GmailAppのsearchメソッドでは、スレッドという単位で、メールが取得されます。
スレッドの中には、複数のメッセージ(メール)が格納されているので、for文を利用して、
一つひとつメールの内容をチェックしていきます。
以下2つの内容をチェックします。
その1. メール受信時間
GmailAppでは、メールをスレッド単位で取得しているため、スレッド内すべてのメールが取得されてしまいます。
そのため、スレッドから取得したメールの受信日時を再度チェックして、10分前のメールであるかをチェックします。
また、更にここで、受信から5分以上経過しているかをチェックします。
その2. メール本文
メールの本文をチェックして、「サイトから応答がなく、スキャン停止した場合に送信されるメール」であるかを確認します。
該当のメールが見つかったら、ステップ4の再スキャンを行います。
また、スキャン再開時に必要となる、スキャンIDも、メール本文から取得します。
//スレッド数分繰り返し
threads.forEach(function(thread) {
// スレッド内のメールを取得
let messages = thread.getMessages();
// メールを一つずつ取り出す
messages.forEach(function(message) {
var before10Date = new Date(before10Time);
var before5Date = new Date(before5Time);
//メールの受信日時が10分前以内 かつ 5分以上前の場合が対象
if (message.getDate() >= before10Date
&& message.getDate() <= before5Date) {
// メール本文を取得
let plainBody = message.getPlainBody();
// スキャン失敗の場合
if (plainBody.includes('サイトからの応答が無いためスキャンを一時停止しました')) {
var mScanId = plainBody.match(/スキャン名: ID:([0-9]+)\./);
var scanId = mScanId[1];
console.log('スキャンIDをメールから取得:' + scanId);
//スキャン再開
Logger.log('サイトから応答が無い状態が5分続いたためスキャンID:' + scanId + ' の再スキャンを実行');
resumeScan(scanId);
}
}
});
});
ステップ4(再スキャンの実行)
最後にAeyeScanのAPIを実行して、再スキャンを実行します。
呼び出すAPIは、スキャン再開のAPIとなります。
//再スキャンを実行する
function resumeScan(scanId) {
//再スキャンAPIを実行する
try{
const api_scan_url = API_BASE_URL + scanId + API_RESUME_SCAN;
const api_scan_params = { "method":"PUT",...API_HEADERS_PARAMS,"payload":JSON.stringify({"speed": "normal"}) };
UrlFetchApp.fetch(api_scan_url, api_scan_params);
Logger.log("スキャン再開: " + scanId);
}catch(err){
Logger.log("スキャン再開エラー" + err );
}
}
検証
スクリプトが完成したので、さっそく実行してみましょう。
トリガーの設定
今回は、5分毎にスクリプトを実行するため、「時間主導型」、「分ベースのタイマー」、「5分おき」で設定をおこないます。
スキャンを作成します。
スキャン作成の際は「メール通知設定」でご自身のGMailに通知されるように設定しておきます。
検証のためサンプルサイトを意図的に停止します。
以下のようにスキャンが自動で停止し、通知内容が表示さます。
ちなみに、GASの実行ログを確認すると、問題なく、再スキャンが実行されていることを確認できます。
利用上の注意
今回利用したコードについては、自由に編集しご利用ください。ただし、無償無保証のため不明点の質問やカスタマイズについてのサポートはできません。コードの改善、不具合については、是非ご連絡ください。
おわりに
今回は、GASとAeyeScanのAPIを利用して、スキャンを自動再開する仕組みを作成しました。
また、Gmailをご利用でない場合は、今回の仕組みをAeyeScanのCustom Webhook機能と他自動化ツールを利用して、作成することも可能です。
是非ご活用ください。
参考文献
Google Apps ScriptでGmailの情報を取得する際に、受信日時を細かく指定する方法。
https://qiita.com/3mc/items/39b2c8241c6b52811ad2
AeyeScanのトライアル、脆弱性診断の自動化のご相談はこちら