こんにちは、Accessブロガーのなかぜんです。
「パラメータクエリ、便利なんだけど…何か不安がある」そんな風に思ったことはありませんか?Accessでフォームやクエリを使って動的にデータを絞り込むのは簡単で、初心者でも扱いやすい仕組みですが、実はパラメータの使い方によっては、重大なセキュリティリスクにつながることもあるんです。
今回は、Accessでのクエリパラメータの脆弱性とその対策法について、業務でも使える実例を交えて解説していきます。
クエリパラメータの脆弱性とは?
フォームの入力値がそのままSQL文に入る危険性
Accessでは、クエリに以下のようなパラメータ式を使ってフィルタ処理を行うことがよくあります。
SELECT * FROM T_社員 WHERE 氏名 = [フォーム]![F_検索フォーム]![txt氏名];
一見、使いやすい仕組みですが、フォーム入力値に「' OR 1=1 --
」のようなSQL構文が紛れ込んだ場合、すべてのレコードが抽出されてしまうことがあります。これがいわゆるSQLインジェクションです。
Accessでは自動でプレースホルダー処理は行われないため、ユーザー入力を直接SQLに組み込む場合は注意が必要です。
安全な実装法:VBAによるパラメータ制御
VBA+QueryDefを使って安全に値を渡す
VBAからパラメータを渡す場合は、QueryDef
オブジェクトを使うことで、入力値を安全に扱えます。
' 安全なパラメータ渡しの例
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb
Set qdf = db.QueryDefs("Q_社員検索")
qdf.Parameters("氏名") = Me.txt氏名
Dim rs As DAO.Recordset
Set rs = qdf.OpenRecordset
' rsをフォームなどに連携して表示
このようにQueryDef.Parameters()
を使えば、Accessが適切にクォート処理してくれるため、SQLインジェクションのリスクを回避できます。
SQLを組み立てる際の注意点
SQL文をVBAで動的に組み立てる場合も、直接文字列を連結するのではなく、プレースホルダー的にQueryDefやPrepared Statementsの形を意識しましょう。
注意点:ありがちなミスとその対処法
- フォームコントロールがNullでもWHERE句が生成されてしまう:Nullチェックを事前に行いましょう。
- 文字列結合でシングルクォートのエスケープ忘れ:「’」が含まれた氏名などが原因でSQLエラーに。
- QueryDefオブジェクトを使わずにSQL文を直接書く:簡単ですがセキュリティ的に弱くなりがちです。
応用ポイント:ログ出力と監視の仕組み
セキュリティを高めるなら、検索クエリの履歴や入力内容をログとして記録することも有効です。
Call WriteLog("検索実行:" & Me.txt氏名)
ログ出力には、FileSystemObject
でログファイルを作ったり、専用のT_ログテーブルに記録したりするのが一般的です。
万が一、不審な値が記録されていた場合に、すぐ気づける体制を整えることが重要です。
まとめ:Accessでもセキュアな設計を
Accessは手軽で強力な開発ツールですが、パラメータの扱いには意外と落とし穴があります。
今回のポイントをおさらいすると:
- フォーム値を直接クエリに使うのは危険
- VBAの
QueryDef
を使ってパラメータを渡す - ログ機能や入力チェックで多重防御を
これらを意識することで、業務でも安心してAccessアプリを運用できるようになります。
「なんとなく使ってたクエリ、ちょっと見直してみようかな」と思っていただけたら嬉しいです!
