【テクニカル・上級編】QueryDefの「隠し属性」を活用したシステム管理:ユーザーに見せない管理用クエリの動的生成 – Access VBA解析バイブル

スポンサーリンク

幽霊のようなクエリ:QueryDefの「隠し属性」による動的セキュリティの極致

Accessにおける`QueryDef`は、単なるクエリの保存先ではない。それはシステムの「実行エンジン」に直接介入するためのインターフェースだ。多くの開発者は「クエリを保存して、GUIで実行する」というレベルで止まっているが、真のアーキテクトは、実行の瞬間に生成し、痕跡を残さずに消滅させるという「一過性のアーキテクチャ」を設計する。

今回は、管理者権限の境界線上で機能する、セキュリティを担保した「隠しクエリ」の極限実装術を伝授する。

—

1. なぜ「隠し属性(Hidden)」なのか

Accessの`TableDef`や`QueryDef`には、Attributesプロパティが存在する。ここに`dbHiddenObject`定数を与えることで、ナビゲーションウィンドウから当該オブジェクトを物理的に隠蔽できる。

しかし、真の目的は「隠すこと」そのものにはない。「システムメタデータに永続化させない」ことにある。クエリを保存し続けることは、肥大化するデータベースの断片化を招き、セキュリティリスク(SQLの覗き見)を高めるだけだ。

我々が目指すのは、「メモリ上にのみ存在するクエリ」である。

—

2. 動的QueryDefの構築とメモリ最適化の真髄

`CreateQueryDef`メソッドに名前を与えず空文字(`””`)を渡すと、それは一時的なクエリとして生成される。これを適切に解放しなければ、Accessのエンジンはメモリリークを起こす。

以下のコードは、高セキュリティかつ低負荷な動的SQL実行のテンプレートだ。

‘ 伝説的なアーキテクトが教える、一過性クエリの実行パターン
Public Function ExecuteSecureQuery(ByVal sqlStatement As String, ParamArray params() As Variant) As Boolean
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim prm As DAO.Parameter
Dim i As Integer

Set db = CurrentDb

‘ 名前を空文字にすることで、ナビゲーションウィンドウには一切表示されない
‘ 一時的なQueryDefとして生成する
Set qdf = db.CreateQueryDef(“”, sqlStatement)

On Error GoTo Cleanup

‘ パラメータのバインド(SQLインジェクション対策)
If UBound(params) >= 0 Then
For i = 0 To UBound(params)
qdf.Parameters(i).Value = params(i)
Next i
End If

‘ 実行(戻り値が不要なアクションクエリを想定)
qdf.Execute dbFailOnError
ExecuteSecureQuery = True

Cleanup:
‘ 【重要】オブジェクトの明示的解放
‘ ここを疎かにするエンジニアがシステムを崩壊させる
If Not qdf Is Nothing Then
qdf.Close
Set qdf = Nothing
End If
Set db = Nothing

If Err.Number <> 0 Then
‘ エラーログ処理をここに実装
ExecuteSecureQuery = False
End If
End Function

—

3. レガシー環境でのAPI活用:プロセスの完全分離

もし、さらに強固なセキュリティを求めるなら、Windows APIを用いて「実行権限のコンテキスト」を切り替える必要がある。例えば、管理用クエリを実行する瞬間だけ、特定のログファイルを書き換えるAPIコールや、メモリ上のSQL文字列を暗号化する処理を噛ませる。

`kernel32`の`ZeroMemory`を用いて、処理後に変数のメモリ領域を0クリアする手法は、軍事レベルのセキュリティ要件では必須だ。

‘ メモリ上の機密情報を破棄するためのAPI定義
Private Declare PtrSafe Sub ZeroMemory Lib “kernel32” Alias “RtlZeroMemory” (dest As Any, ByVal numBytes As LongPtr)

‘ 使用例:SQL文字列を使い終わった後にメモリを消去
‘ Dim sql As String: sql = “…”
‘ ZeroMemory ByVal StrPtr(sql), LenB(sql)

—

4. アーキテクトの視点:システム管理への応用

この手法を応用すれば、以下のような堅牢な運用が可能になる。

  • 動的権限管理: `CurrentUser()`やログインテーブルを参照し、条件を満たした時のみ`CreateQueryDef`を生成・実行。それ以外は即座にエラーを投げる。
  • トレースの無効化: 保存されたクエリではないため、Accessのパフォーマンスアナライザやサードパーティの解析ツールに痕跡を残さない。
  • インジェクション防御: `QueryDef`のパラメータオブジェクトを介すことで、VBA文字列結合によるSQLインジェクションを物理的に無効化する。

結論

「保存する」ことは怠惰である。真のエンジニアは、必要な時にのみ存在し、役目を終えれば霧のように消えるコードを書く。

Access VBAは、正しく扱えば現代のクラウドネイティブなAPI開発にも比肩する柔軟性を備えている。ナビゲーションウィンドウに並ぶクエリは、単なる「遺物」だ。動的生成こそが、システムの寿命を延ばし、守りを堅くする唯一の正攻法である。

コードに魂を込めろ。メモリの隅々まで掌握し、痕跡を残すな。それが、この領域における「プロフェッショナル」の流儀だ。

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