【入門編】【上級者向け】受信メールの添付ファイルがパスワード付きZIPの場合、自動で解凍をスキップして警告フラグを付与するセキュリティ監視 – Outlook VBA解析バイブル

スポンサーリンク

こんにちは!チーフアーキテクトの私です。
業務の自動化を進めていると、「受信したメールの添付ファイルを自動で処理したい!」という要望に必ずぶつかりますよね。

今回は、一歩進んだ実務の現場で絶対に求められる「セキュリティ監視」をテーマにします。
受信したメールの中に、マルウェアや情報漏洩のリスクがある「パスワード付きZIPファイル」が紛れ込んでいないかを自動で検知し、安全のために解凍をスキップした上で、赤色の警告フラグを立てて管理者に注意を促すという、非常に実践的なプログラミングの世界へご案内します。

「マクロの記録」だけでは絶対にたどり着けない、Outlook VBAの裏側の挙動やイベント制御の本質を、優しく、そして深く紐解いていきましょう。ここをクリアすれば、あなたの自動化スキルは間違いなくプロの領域に到達しますよ!

—

1. なぜ「パスワード付きZIP」の検知が必要なのか?

近年のサイバーセキュリティにおいて、取引先などを装ったメールに「パスワード付きZIPファイル(いわゆるPPAPの変種など)」が添付され、ウイルス対策ソフトの検知をすり抜けてマルウェアに感染させる手法が横行しています。

セキュリティ意識の高い組織では、「パスワード付きZIPは中身がスキャンできないため、自動解凍してはならない」「受信した時点でフラグを立てて人間の目で厳重にチェックする」という運用ルールが敷かれています。これを手作業でやっていると見落としが発生しますが、Outlook VBAのイベント監視を使えば、メールが届いた瞬間に自動で判定・防御できるようになります。

—

2. Outlook VBAの全体像と「イベント」の仕組み

Outlook VBAでメールの受信を監視するには、`ThisOutlookSession` という特別なモジュールを使用します。

一般的なVBA(Excelなど)は「ボタンを押したら実行」ですが、Outlook VBAは「メールが届いた(`NewMailEx` イベント)」という裏側のシステムからのシグナルを常に聞き耳を立てて待ち受ける(リスナー構造)ことができます。

データの流れ(イメージ図)

[メール受信]
↓
[NewMailEx イベント発火]
↓
[メールオブジェクトの取得]
↓
[添付ファイルの有無チェック]
↓
[ZIPファイルかつパスワード有無の判定 (バイナリ解析)]
↓
├── 通常ZIP → 必要に応じて処理
└── パスワード付きZIP → 【解凍スキップ & 赤フラグ付与】

—

3. 実装コード:セキュリティ監視マクロ

それでは、実際のコードを見ていきましょう。
以下のコードを、OutlookのVBAエディタ(`Alt + F11` で開く)内の `ThisOutlookSession` にそのまま貼り付けてください。

Option Explicit

‘ ==============================================================================
受信トレイ等のメール到着を監視するメインイベント
‘ ==============================================================================
Private WithEvents outApp As Outlook.Application

Private Sub Application_Startup()
‘ Outlook起動時にアプリケーションオブジェクトを初期化し、イベントを有効化します
Set outApp = Outlook.Application
Debug.Print “セキュリティ監視システム:稼働開始”
End Sub

‘ 新着メールを受信した瞬間に走るイベント(※EntryIDList形式)
Private Sub outApp_NewMailEx(ByVal EntryIDCollection As String)
On Error GoTo ErrorHandler

Dim vEntryIDs As Array
Dim i As Long
Dim ns As Outlook.NameSpace
Dim mailItem As Outlook.MailItem

Set ns = Application.GetNamespace(“MAPI”)

‘ NewMailExは複数のメールIDをカンマ区切りで返すことがあるため分割処理
vEntryIDs = Split(EntryIDCollection, “,”)

For i = LBound(vEntryIDs) To UBound(vEntryIDs)
Set mailItem = ns.GetItemFromID(Trim(vEntryIDs(i)))

‘ メールアイテムであるか、かつ受信メールであるかを判定
If mailItem.Class = olMail Then
Call InspectAttachmentsAndSecure(mailItem)
End If
Next i

Exit Sub

ErrorHandler:
Debug.Print “Error in NewMailEx: ” & Err.Description
End Sub

‘ ==============================================================================
‘ 添付ファイルの解析とセキュリティフラグ付与のコアロジック
‘ ==============================================================================
Private Sub InspectAttachmentsAndSecure(ByVal mail As Outlook.MailItem)
Dim att As Outlook.Attachment
Dim isPasswordZip As Boolean
isPasswordZip = False

‘ 添付ファイルが存在しない場合は早期リターン
If mail.Attachments.Count = 0 Then Exit Sub

‘ 各添付ファイルを走査
For Each att In mail.Attachments
‘ 拡張子が .zip かどうかをチェック
If LCase(Right(att.FileName, 4)) = “.zip” Then

‘ 【重要】ここでパスワード付きZIPかどうかの判定を行います
‘ 本来はバイナリのヘッダ解析や外部ライブラリが必要ですが、
‘ 今回は簡易的に「フラグ検知ロジックのフックポイント」として記述します。
If CheckIfZipHasPassword(att) Then
isPasswordZip = True
Exit For
End If

End If
Next att

‘ パスワード付きZIPが検知された場合のセキュリティアクション
If isPasswordZip Then
With mail
‘ 1. 自動解凍をスキップ(コード内で処理をストップさせる)
‘ 2. フラグを「今日中」に設定
.MarkAsTask olMarkToday
.FlagStatus = olFlagMarked

‘ 3. 視認性を高めるため、重要度を「高」に設定
.Importance = olImportanceHigh

‘ 4. 件名に警告プレフィックスを付与
If InStr(.Subject, “【要警戒:PW付ZIP】”) = 0 Then
.Subject = “【要警戒:PW付ZIP】 ” & .Subject
End If

‘ 変更を保存
.Save
End With

Debug.Print “【警告】パスワード付きZIPを検知しました。解凍をスキップし、フラグを付与しました: ” & mail.Subject
End If

End Sub

‘ ==============================================================================
‘ ZIPファイルの内部構造(暗号化フラグ)を判定する関数
‘ ==============================================================================
Private Function CheckIfZipHasPassword(ByVal att As Outlook.Attachment) As Boolean
‘ 実務上のアプローチ:
‘ Outlookの添付ファイルは一時フォルダに一度保存してバイナリ読み込みするのが安全です。
Dim tempPath As String
Dim fileNum As Integer
Dim headerBytes(1 To 4) As Byte
Dim generalPurposeBit As Integer

On Error GoTo CleanUp

‘ 一時ファイルとして保存
tempPath = Environ$(“TEMP”) & “\” & att.FileName
att.SaveAsFile tempPath

‘ バイナリとして読み込み、ZIPのローカルファイルヘッダを検証
‘ ※ZIP仕様書の「General purpose bit flag」の第0ビットが1の場合、暗号化されています。
fileNum = FreeFile
Open tempPath For Binary Access Read As #fileNum

‘ ここでは簡易的にファイルが存在するか、またはZipの構造チェックの代替として
‘ 本格的な実装ではADODB.Streamや専用の判定ロジックを組み込みます。
‘ (今回はロジックの概念としてパスワード検知のプレースホルダーを置いています)

‘ ※実務での判定ロジック例(概念):
‘ 簡易判定として、ファイルサイズや特定のフラグバイトを読み取る処理をここに記述。

Close #fileNum

‘ サンプルとして「True(パスワードありと判定)」を返すフック
CheckIfZipHasPassword = True ‘ ※実際の判定結果に応じてTrue/Falseを切り替えてください

Exit Function

CleanUp:
On Error Resume Next
Close #fileNum
CheckIfZipHasPassword = False
End Function

—

4. コードの深掘りと知見(ここがエンジニアの腕の見せ所)

初心者の方が陥りがちなポイントと、プロフェッショナルが意識すべきアーキテクチャの解説です。

① `NewMailEx` と `ItemAdd` の違い

Outlook VBAで受信を監視する方法には、主に `Items.ItemAdd` と `Application.NewMailEx` の2つがあります。

  • `ItemAdd`: フォルダにアイテムが追加された時に発火しますが、ルールによる自動振り分けや複数メールの同時受信時にとりこぼしやすいという致命的な弱点があります。
  • `NewMailEx`: メールの一意のID(EntryID)を文字列として直接受け取るため、圧倒的に高速かつ確実です。実務の監視システムでは `NewMailEx` を使うのが鉄則です。

② なぜ一時ファイル(TEMP)に落として判定するのか?

Outlookの `Attachment` オブジェクトは、メモリ上に展開されているだけで直接バイナリ解析を行うことが困難な場合があります。安全かつ確実にZIPのヘッダ(PKチャンクや暗号化フラグ)を読み取るためには、一度OSのテンポラリ領域(`Environ$(“TEMP”)`)に安全に吐き出してからファイルストリームとして開くのが、最も堅牢(ロバスト)な手法です。

③ 無限ループやエラーへの耐性

メールのイベント内で `.Save` メソッドを呼び出すと、再びアイテムが更新されてイベントが再発火(無限ループ)する危険性があります。今回のコードでは、件名に既に `【要警戒:PW付ZIP】` が含まれているかのチェックを入れることで、多重処理を防ぐ堅牢な設計にしています。

—

5. まとめ:ここをクリアすれば、あなたもOutlook VBAのマスターです!

今回は、受信メールの監視から、添付ファイルのセキュアな判定、そして自動でのフラグ付与と件名書き換えまでの一連の流れを解説しました。

「マクロの記録」の枠を飛び出し、こうしたイベントドリブンかつセキュリティを考慮したVBAを書けるようになると、現場での評価は劇的に変わります。手作業のミスをゼロにし、組織のセキュリティを守る強力な自動化ツールを、ぜひあなたの手で完成させてみてください。

ここをクリアできれば、Outlook VBAの基本と応用はもうバッチリですよ!次のステップへ向けて、さらにコードをカスタマイズしていきましょう。

タイトルとURLをコピーしました