【実務・中級編】【SQLインジェクション対策】ADODB.Command パラメータ化クエリによるセキュアなデータベース操作の実装 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptでデータベースを叩くなら「文字列結合」を即刻やめろ:ADODB.Commandによる鉄壁のSQL構築術

業務自動化の現場でVBScriptは今なお現役だ。しかし、多くのエンジニアが「動けばいい」という甘い考えで書いたコードが、セキュリティホールという時限爆弾を抱えている事実に気づいていない。

特に、データベース連携においてSQL文を文字列結合で組み立てる手法は、SQLインジェクションという致命的な脆弱性を招く。今日は、伝説的なアーキテクトとして、この「悪しき習慣」を根絶し、`ADODB.Command` を用いた堅牢な実装へと昇華させるための極意を伝授する。

—

1. なぜ「文字列結合」は悪なのか?

初学者が陥るのが、以下のようなSQL構築だ。

‘ 絶対にやってはいけないNG例
sql = “SELECT FROM Users WHERE UserName = ‘” & userInput & “‘”

もし `userInput` に `’ OR ‘1’=’1` が入力されたらどうなるか? 全データが流出するか、最悪の場合データベースが破壊される。これは単なるバグではない。「SQLの命令」と「データ」を混同させている構造そのものが欠陥なのだ。

このリスクを回避するための唯一の解が、パラメータ化クエリ(Parameterized Queries)である。

—

2. ADODB.Commandによる「型」と「値」の分離

`ADODB.Command` オブジェクトを使う最大の利点は、SQLテンプレートとパラメータをエンジンレベルで分離できることだ。これにより、入力された値は「単なる文字列」としてのみ解釈され、決して「SQLコマンドの一部」としては実行されない。

実装の極意:プロダクションコード

保守性と安全性を極限まで高めた実装例を示す。これをテンプレートとして活用してほしい。

Option Explicit

‘ データベース操作関数:安全な検索処理
Function GetUserData(sConnStr, sUserName)
Dim oConn, oCmd, oRS

‘ オブジェクト生成
Set oConn = CreateObject(“ADODB.Connection”)
Set oCmd = CreateObject(“ADODB.Command”)

On Error Resume Next

oConn.Open sConnStr
Set oCmd.ActiveConnection = oConn

‘ クエリのテンプレート化(? はプレースホルダ)
oCmd.CommandText = “SELECT UserID, Email FROM Users WHERE UserName = ?”
oCmd.CommandType = 1 ‘ adCmdText

‘ パラメータを明示的に追加 (型、方向、サイズ、値)
‘ adVarWChar(202), adParamInput(1)
oCmd.Parameters.Append oCmd.CreateParameter(“@UserName”, 202, 1, 50, sUserName)

‘ 実行
Set oRS = oCmd.Execute

If Not oRS.EOF Then
GetUserData = oRS(“Email”).Value
Else
GetUserData = Null
End If

‘ 後処理(リソース解放は必須)
oRS.Close
oConn.Close

Set oRS = Nothing
Set oCmd = Nothing
Set oConn = Nothing

If Err.Number <> 0 Then
WScript.Echo “Error: ” & Err.Description
End If
End Function

—

3. なぜこのコードが「強い」のか

A. 型の制約(Type Enforcement)

`CreateParameter` でデータ型(例: `202` = `adVarWChar`)を指定している点が重要だ。これにより、データベースエンジンは受け取る値を厳密に検証し、予期せぬ挙動を未然に遮断する。

B. 明示的なリソース解放

VBScriptのガベージコレクションを信用してはいけない。`Set Object = Nothing` を徹底することで、大規模なループ処理や長時間実行される自動化ツールにおけるメモリリークを防ぐ。これは、プロフェッショナルが守るべき最低限の規律だ。

C. 保守性の担保

SQL文をコードの中にハードコーディングせず、パラメータのみを差し替える構造にすることで、DBの仕様変更時にも修正箇所を最小限に抑えられる。

—

4. エンジニアへのラストアドバイス

業務自動化ツールを作る際、最も怖いのは「動くコード」ではなく「脆弱なコード」だ。

1. 入力値はすべて疑え: `CreateParameter` は、外部からの入力を安全に扱うための唯一の盾だ。
2. エラーハンドリングを怠るな: `On Error Resume Next` を使うなら、必ず `Err.Number` をチェックし、ログに残す仕組みを実装すること。
3. 複雑性を排除せよ: コードはシンプルであればあるほどバグは減る。`ADODB.Command` は一見遠回りに見えるかもしれないが、将来の「修正コスト」を激減させる賢明な投資だ。

このコードをコピー&ペーストするだけでなく、なぜこの構造が必要なのかを噛み締めてほしい。それが、スクリプターから「熟練の自動化アーキテクト」へ進化するための第一歩となる。

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