【実務・中級編】QueryDefの実行権限を制御する:特定のユーザーのみが実行可能な「管理用クエリ」の隠蔽術 – Access VBA解析バイブル

スポンサーリンク

Access VBAの深淵:管理用クエリを「存在させない」究極のセキュリティ実装術

Access開発の現場で、一度は頭を悩ませるのが「管理機能の保護」だ。
「管理者のみが実行できるクエリ」をそのままナビゲーションウィンドウに放置していないだろうか? あるいは、`CurrentDb.Execute` で直接SQLを流し込んで満足していないだろうか?

本稿では、DAOの`QueryDef`オブジェクトを最大限に活用し、「必要な時に生成し、用が済んだら物理的に消滅させる」という動的クエリ管理術を伝授する。これは単なる小手先のテクニックではない。データベースのメタデータ層を掌握し、攻撃対象領域(アタックサーフェス)を最小化するアーキテクトの矜持だ。

—

なぜ「作り置きのクエリ」は脆弱なのか

多くの開発者がやりがちな「管理用クエリをあらかじめ作っておく」手法は、以下の理由で論外である。

1. ナビゲーションウィンドウからの露出: 非表示設定などは、知識のあるユーザーには無力だ。
2. 権限管理の限界: Access標準のユーザーレベルセキュリティは現代では脆弱かつ保守が困難だ。
3. 汚染されたDB構造: 不要なオブジェクトが残ることで、データベースのメタデータが肥大化し、最適化の妨げになる。

我々が目指すべきは、「実行プロセスにおいてのみ存在し、実行直後に消滅するエフェメラル(一時的)なクエリ」である。

—

実装設計:QueryDefのライフサイクル管理

以下のコードは、権限チェックを通過した管理者のみが、動的に作成された安全な`QueryDef`を実行するパターンだ。

プロダクションコード:セキュアな動的クエリ実行クラス

‘ ———————————————————————-
‘ モジュール名: AdminQueryManager
‘ 概要: 実行時のみクエリを生成し、終了と共に破棄することで痕跡を消す
‘ ———————————————————————-
Option Compare Database
Option Explicit

Public Sub ExecuteAdminQuery(ByVal sqlStatement As String, ByVal isAdmin As Boolean)
Dim qdf As DAO.QueryDef
Const QRY_NAME As String = “tmp_AdminTask_Internal”

‘ 1. 厳格な権限チェック
If Not isAdmin Then
MsgBox “権限がありません。アクセスは拒否されました。”, vbCritical
Exit Sub
End If

On Error GoTo Cleanup

‘ 2. 既存の同名クエリがあれば削除(クリーンな状態を担保)
On Error Resume Next
CurrentDb.QueryDefs.Delete QRY_NAME
On Error GoTo Cleanup

‘ 3. 管理用クエリの動的生成
Set qdf = CurrentDb.CreateQueryDef(QRY_NAME, sqlStatement)

‘ 4. パラメータや実行処理(必要に応じて記述)
‘ qdf.Parameters(“[ID]”) = 123
qdf.Execute dbFailOnError

MsgBox “管理処理が正常に完了しました。”, vbInformation

Cleanup:
‘ 5. 痕跡の完全消去
If Not qdf Is Nothing Then Set qdf = Nothing
On Error Resume Next
CurrentDb.QueryDefs.Delete QRY_NAME

If Err.Number <> 0 Then
Debug.Print “Error ” & Err.Number & “: ” & Err.Description
End If
End Sub

—

この実装が「最強」である理由

1. 物理的な痕跡を残さない

`CurrentDb.QueryDefs.Delete`を確実に実行することで、データベースのクエリ一覧には何も残らない。万が一、ユーザーがmdb/accdbを直接開いたとしても、そこには「管理者用のコード」は存在しないのだ。

2. SQLインジェクションへの耐性

`QueryDef`を使用することで、Accessのクエリエンジンを通したパラメータクエリ化が容易になる。`CurrentDb.Execute`に文字列を連結して渡すような、素人じみた実装とは一線を画す堅牢性を担保できる。

3. エラーハンドリングの徹底

`dbFailOnError`フラグを使用し、トランザクションの整合性を保証している。もしSQLが失敗した際も、`Cleanup`ラベルで確実にクエリを削除する設計にしているため、ゴミオブジェクトがシステムに溜まることはない。

—

アーキテクトからの提言:さらなる高みへ

この手法を極めるならば、以下のステップへ進め。

  • SQLの難読化: SQL文をコード内にハードコーディングせず、暗号化されたテーブルから読み込んで実行時に復号する。
  • イベントログの記録: 誰が、いつ、どのクエリを実行したかを別個の監査ログテーブルへ自動的に書き込むロジックを`ExecuteAdminQuery`内に組み込む。

Accessは「おもちゃ」ではない。設計次第で、堅牢な基幹業務システムを支える強力なエンジンに化ける。不要なオブジェクトを排し、実行の瞬間だけを輝かせる。これこそが、DAOのポテンシャルを極限まで引き出すプロの所業だ。

さあ、あなたのコードから「不要なクエリ」を一掃し、真の安全を手に入れよ。

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