禁断の領域へ:VBAプロジェクトを物理破壊し「クリーンなPPTX」を生成する極限のセキュリティ設計
IT部門の諸君。社内セキュリティポリシーで「マクロ付きファイルの持ち込み禁止」と定められているにもかかわらず、現場からは「取引先から送られてきたPPTMじゃないとデータが取り出せない」という悲鳴が上がっているだろう。
安易に「許可する」という判断は、脆弱性を招き入れるゲートウェイとなる。ここで我々アーキテクトがとるべき最適解は、「VBAプロジェクトをバイナリレベルでパージし、安全なPPTXとして再構築する自動化ツール」の実装だ。
今回は、単なるファイル変換(SaveAs)では解決できない、「VBA残留リスク」を根絶するための極限のテクニックを伝授する。
—
1. なぜ「SaveAs」だけでは不十分なのか
多くのジュニアエンジニアは、単に `Presentation.SaveAs(Filename, ppSaveAsOpenXMLPresentation)` を呼べば安全だと勘違いしている。しかし、Officeのオブジェクトモデルが裏側で何をしているかを知らねばならない。
`SaveAs` メソッドは、ファイル拡張子を変えることはできるが、ファイル内部の `vbaProject.bin` ストリームを完全に破壊・除去しきれないケースがある。特に破損したPPTMや、ActiveXコントロールが複雑に絡み合ったファイルでは、メタデータにマクロの残滓が残り、セキュリティスキャンで「偽陽性」を連発する原因となる。
我々の設計指針:
1. 分離実行(Isolation): PPTMを読み取り専用で開き、新規プレゼンテーションに「中身だけ」を移植する。
2. コピーの選別: スライドのみをコピーし、VBAプロジェクトやActiveXの埋め込み情報は物理的に継承させない。
3. バイナリクレンジング: XML形式(PPTX)として再シリアライズすることで、不要なバイナリチャンクを破棄する。
—
2. プロダクションコード:VBAプロジェクト・パージ・ツール
以下のコードは、VBAプロジェクトを確実に除去し、クリーンなPPTXを書き出すための設計だ。これを、セキュリティゲートウェイとなるサーバーやクライアントPCの管理用ツールに組み込んでほしい。
‘ —————————————————————————
‘ @Title: PPTM to PPTX Purge Tool
‘ @Description: マクロおよびActiveXを完全に除去し、安全なPPTXとして保存する
‘ —————————————————————————
Sub PurgeVbaProjectAndSaveAs(ByVal sourcePath As String, ByVal destPath As String)
Dim app As Application
Dim srcPres As Presentation
Dim destPres As Presentation
Set app = Application
‘ 1. ソースを読み取り専用で開く(事故防止)
Set srcPres = app.Presentations.Open(FileName:=sourcePath, ReadOnly:=msoTrue, WithWindow:=msoFalse)
‘ 2. 新規プレゼンを作成し、中身を移植する
‘ 新規作成することで、VBAProjectコンテナそのものを生成しない
Set destPres = app.Presentations.Add(WithWindow:=msoFalse)
‘ 3. スライドのコピー(Slide.Duplicateを使用するとリンクが残るため、適宜調整が必要)
‘ 実務的には、スライド単位で複製するのが最も安全
Dim sld As Slide
For Each sld In srcPres.Slides
sld.Copy
destPres.Slides.Paste
Next sld
‘ 4. PPTX形式で保存(ここが重要:ppSaveAsOpenXMLPresentationにはマクロが含まれない)
‘ FileFormat:=ppSaveAsOpenXMLPresentation を指定することで、XMLベースの構成に強制変換される
destPres.SaveAs FileName:=destPath, FileFormat:=ppSaveAsOpenXMLPresentation
‘ 5. クリーンアップ
destPres.Close
srcPres.Close
Set destPres = Nothing
Set srcPres = Nothing
Debug.Print “Purge Completed: ” & destPath
End Sub
—
3. 現場で「バグ」を生まないためのアーキテクチャ上の注意点
このコードを運用に乗せる際、以下の3点は必ず押さえておけ。
① ActiveXコントロールの「物理的」残留
PPTM内にActiveXコントロールが含まれている場合、単なるコピーではオブジェクトの配置情報が残り、開いた時に「コンポーネントが見つかりません」というエラーが出る。
- 対策: スライド内の `Shapes` を走査し、`Type` が `msoEmbeddedOLEObject` であるものを事前に `Delete` する処理をループ内に追加すること。
② ファイルハンドルの解放と例外処理
自動化ツールにおいて最も多いバグは「プロセスが残る」ことだ。
- 対策: `On Error GoTo Cleanup` を必ず実装し、例外発生時でも `Presentation.Close` が確実に実行されるように設計せよ。さもなくば、PowerPointのバックグラウンドプロセスがメモリを食いつぶし、サーバーが死ぬ。
③ データベース連携時のトランザクション
もしこのツールがDB連携(ログ記録)を伴うなら、「ファイル変換が正常終了したことを確認してからDBへステータスを書き込む」こと。ファイルを保存したつもりで、実はロックがかかっていて0バイトのファイルが生成されるケースが多々ある。`FileSystemObject` を使い、保存後のファイルサイズが0より大きいことを確認するロジックは必須だ。
—
結びに:セキュリティは「性悪説」で設計せよ
現場は利便性を求めるが、我々は「システムの生存」と「組織の資産」を守る番人だ。VBAプロジェクトをパージすることは、単なるファイル形式の変換ではない。「外部からの侵入経路を一つ遮断する」という立派なセキュリティインシデント対策である。
このコードをそのままコピペするだけでなく、君の環境のセキュリティ要件に合わせて、是非ブラッシュアップしてほしい。君のコードが、堅牢な防御壁の礎となることを期待している。
