SQL Serverへの移行ステップ:SSMA for Accessを使ってみよう
nanikatoaccess
なにか to Access
以下では、「SQLインジェクションとは無縁?入力チェックとパラメータ化クエリの重要性」をテーマに、Microsoft Accessで起こり得るSQLインジェクションリスクを解説しつつ、安全にデータを扱うための対策を紹介します。「AccessはデスクトップDBだから大丈夫」と思いがちですが、フォームやクエリで文字列連結によるSQL操作を行っていると、思わぬ抜け穴になることがあります。しっかりとした入力チェックやパラメータ化クエリを実践し、安全なシステムを運用しましょう。
SQLインジェクションは、ユーザーからの入力をそのままSQL文に組み込むことで、意図しないクエリが実行されてしまう攻撃手法です。
WHERE 顧客名 = 'X' OR '1'='1'
のように書き換えられ、検索条件を無視してすべてのデータを取り出してしまうなど。なぜAccessでも危険?
strSQL = "SELECT * FROM 顧客 WHERE 名前='" & Me.txt検索 & "'"
のようにやると、悪意ある文字列(' OR '1'='1
など)を仕込まれる可能性がある。Replace
関数で '
を ''
にエスケープなど)Public Function SafeString(strInput As String) As String
' シングルクォートを '' に置き換え(最低限の対策)
SafeString = Replace(strInput, "'", "''")
End Function
AccessでSQLインジェクションを根本的に防ぐには、文字列連結でなく「パラメータクエリ」を利用する方法が推奨されます。
PARAMETERS [顧客名パラメータ] Text ( 50 );
SELECT 顧客ID, 顧客名, 住所
FROM tbl_顧客
WHERE 顧客名 = [顧客名パラメータ];
Public Sub SearchCustomer(strName As String)
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset
Set db = CurrentDb
Set qdf = db.QueryDefs("qry顧客検索")
' パラメータに値を代入
qdf.Parameters("[顧客名パラメータ]") = strName
Set rs = qdf.OpenRecordset()
If Not (rs.EOF And rs.BOF) Then
' 結果処理
Debug.Print "Hit count: " & rs.RecordCount
End If
rs.Close
Set rs = Nothing
Set qdf = Nothing
Set db = Nothing
End Sub
メリット
X' OR '1'='1
のような入力をしても、SQL文そのものが書き換えられないPublic Sub SearchCustomerADO(strName As String)
Dim cn As ADODB.Connection
Dim cmd As ADODB.Command
Dim rs As ADODB.Recordset
Set cn = CreateObject("ADODB.Connection")
' DSNレス接続などでOpen
cn.Open "Provider=SQLOLEDB;Data Source=YourServer;Initial Catalog=YourDB;Integrated Security=SSPI;"
Set cmd = New ADODB.Command
cmd.ActiveConnection = cn
cmd.CommandText = "SELECT 顧客ID,顧客名 FROM dbo.顧客 WHERE 顧客名 = @pName"
cmd.CommandType = adCmdText
' パラメータ定義
cmd.Parameters.Append cmd.CreateParameter("@pName", adVarWChar, adParamInput, 50, strName)
Set rs = cmd.Execute
If Not (rs.BOF And rs.EOF) Then
Debug.Print "Found: " & rs.RecordCount
End If
rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing
End Sub
BeforeUpdate
イベントで空欄や不正文字がないか確認On Error
構文でエラーをキャッチし、分かりやすいメッセージを出す"[顧客名] = '" & Me.txtName & "'"
と書くパターンに要注意[Parameters]
を定義しておかないと型が曖昧になる場合あり'
→ ''
の置換は暫定対策。完全には防ぎきれないケースも"..." & Me.txtInput & "..."
とSQLへ流すと危険'
を ''
に置換するなど本質は「ユーザー入力を何も加工せずSQL文に埋め込むこと」が最も危険だということです。文字列連結が当たり前になっている現場では、パラメータ化クエリへの移行をぜひ検討してください。安全で堅牢なアプリケーションを作ることで、後々のトラブル(データ漏えいや改ざん)を防ぎ、システムの信頼性を高められます。
関連記事
Accessを使ううえでもSQLインジェクションは無縁ではありません。正しい入力チェックとパラメータ化クエリを実践し、安全なAccessシステムを構築していきましょう。