Access VBAを掌握する極限の知見:QueryDefの「SQL難読化」による最終防衛ライン
AccessのQueryDefオブジェクトを覗けば、そこにはビジネスロジックのすべてが記述されたSQLが丸裸で転がっている。開発者が去り、保守担当がコードを追う際、最も脆弱なのは「バックエンドのロジックが誰の目にも明らかである」という事実だ。
コードの難読化(Obsucation)は、単なる気休めではない。これはリバースエンジニアリングに対する「心理的障壁」を築き、安易な改ざんを許さないためのアーキテクトとしての矜持である。今回は、QueryDefに保存されたSQLを暗号化し、実行時にメモリ上で復号・実行する「最終防衛ライン」の構築手法を伝授する。
—
1. なぜQueryDefを暗号化するのか
AccessにおいてQueryDefは、データベースの実行計画を最適化する重要なオブジェクトである。しかし、`.SQL`プロパティはプレーンテキストであり、`CurrentDb.QueryDefs(“q_Sensitive”)`にアクセスするだけで、すべてのロジックが露呈する。
我々が目指すのは、「保存時は無意味な文字列」として保持し、「実行時のみメモリ上でSQLに変換する」というプロセスだ。これには以下の技術的要諦が必要となる。
- 永続化の分離: DBファイル内には暗号化文字列のみを置く。
- メモリ・ライフサイクル管理: 復号されたSQLは変数としてメモリに保持し、実行後は即座に消去する。
- APIによる秘匿: 復号ロジックを標準モジュールに隠蔽し、外部からの直接参照を制限する。
—
2. 実装の核心:SQL難読化エンジン
ここでは、単純なXOR暗号ではなく、BASE64と組み合わせた簡易的な置換アルゴリズムを用いてSQLを保護する。本番環境では、ここにAES等の強力な暗号化APIを組み込むのが定石だ。
難読化・復号モジュール (modSecurity)
Option Explicit
‘ 復号用キー(ハードコードせず、環境変数や別ファイルから読み込むのが理想)
Private Const CRYPTO_KEY As String = “ARCHITECT_SECRET_2024″
”’
”’
Public Sub ExecuteEncryptedQuery(ByVal queryName As String)
Dim qdf As DAO.QueryDef
Dim db As DAO.Database
Dim encryptedSQL As String
Dim decryptedSQL As String
Set db = CurrentDb
Set qdf = db.QueryDefs(queryName)
‘ 暗号化されたSQLを読み込み
encryptedSQL = qdf.SQL
‘ 復号処理(メモリ上でのみ展開)
decryptedSQL = DecryptSQL(encryptedSQL)
‘ 実行計画の生成と実行
‘ 注:本来はここで動的SQLとしてQueryDefを再定義するか、
‘ RunSQLあるいはDAO.Database.Executeを使用する
db.Execute decryptedSQL, dbFailOnError
‘ オブジェクトの解放とメモリのクリーンアップ
Set qdf = Nothing
Set db = Nothing
decryptedSQL = vbNullString ‘ メモリを確実に解放
End Sub
‘ 簡易的な復号ロジック(実際にはCryptoAPI等を使用すること)
Private Function DecryptSQL(ByVal inputData As String) As String
‘ ここに復号アルゴリズムを実装
‘ 難読化を施した文字列から元のSQLを生成する
‘ 戻り値はクリーンなSQL文字列
End Function
—
3. シニアエンジニアが意識すべき「メモリとパフォーマンス」
この手法を用いる際、最も注意すべきは「復号されたSQLがメモリ上にスタックされる時間」である。
1. 文字列の破棄: VBAの文字列変数は、スコープを抜ければ自動的に解放されるが、巨大なSQLを扱う場合は`str = vbNullString`で明示的にメモリ領域を解放する癖をつけよ。
2. DAOオブジェクトのライフサイクル: `CurrentDb`を安易に使い回すな。DAOのDatabaseオブジェクトをキャッシュし、不要になった瞬間に`Set db = Nothing`を叩く。これがメモリリークを防ぐ唯一の道である。
3. パフォーマンスへの影響: 復号コストは、ミリ秒単位で見れば無視できるが、ループ内で何度も呼び出すのは愚策だ。必要な時に一度だけ復号し、メモリにキャッシュする設計を心がけよ。
—
4. 運用の極意:防衛ラインを突破させないために
この難読化は「完璧なセキュリティ」ではない。しかし、Accessというオープンな環境において、「中身を覗く手間を100倍にする」ことは、ビジネス上のリスクヘッジとして極めて有効だ。
- プロシージャのコンパイル: MDE/ACCDE形式での配布を前提とする。これにより、ソースコードそのものへのアクセス権を物理的に遮断する。
- 動的生成の活用: QueryDefそのものをDBに保存せず、VBAコード内に隠蔽した暗号化文字列から、実行時のみメモリ上で`CreateQueryDef`を使用して一時クエリを作成・実行し、終了時に`DeleteQueryDef`する。これが「痕跡を残さない」究極の運用だ。
—
総括:技術を支配せよ
Accessは、しばしば「おもちゃ」と揶揄される。だが、その内部構造を理解し、メモリ管理からセキュリティ設計までを制御下に置く者にとって、これほど強力で高速なプロトタイピング環境は存在しない。
QueryDefのSQLを隠蔽することは、単なるコード保護ではない。それは、君が書いた「ロジック」という名の資産を、泥棒や無理解な改ざん者から守り抜くための、エンジニアとしての最後の砦である。
さあ、今すぐ君のシステムにこの防衛線を構築せよ。アーキテクチャに妥協は許されない。それが、プロフェッショナルというものだ。
