【入門編】VB.NETでのSQLインジェクション完全防御:パラメータ化クエリ(Parameters.AddWithValue)の徹底と動的SQL構築の危険性 – Visual Basic (VB / VB.NET)解析バイブル

スポンサーリンク

SQLインジェクションという「見えない爆弾」を解除せよ:VB.NETにおける安全なSQL操作の極意

こんにちは。現場で長くコードを書き続けていると、たまに「なぜかシステムが不正な挙動を起こしている」「データベースのデータが消えている」といったSOSに出会うことがあります。その原因の多くが、実はSQLインジェクションという脆弱性です。

今日は、VB.NETを扱うエンジニアが絶対に避けては通れない「安全なデータベース操作」の本質を伝授します。初学者の方が陥りやすい罠を解き明かし、今日からプロとして恥じない堅牢なコードが書けるようになりましょう。

1. なぜ「文字列連結」は地獄への入り口なのか?

多くの初心者が、まず最初に書いてしまうコードがあります。これが「悪魔の入り口」です。

.net
‘ 【絶対にやってはいけないコード例】
Dim userName As String = txtInput.Text
Dim sql As String = “SELECT FROM Users WHERE UserName = ‘” & userName & “‘”
‘ もしユーザーが「’ OR ‘1’=’1」と入力したら…
‘ SQLは「SELECT FROM Users WHERE UserName = ” OR ‘1’=’1’」となり、全データが漏洩する!

なぜこれが危険なのか。それは、「プログラムが入力された文字を『データ』として見ているのか、『命令の一部』として見ているのかを区別できていないから」です。

悪意のあるユーザーが入力欄にSQL文を紛れ込ませるだけで、データベースは喜んでその命令を実行してしまいます。これがSQLインジェクションです。

2. 鉄則:パラメータ化クエリ(Parameters)を使え

この脆弱性を一撃で無力化するのが「パラメータ化クエリ」です。「データはデータとして、命令は命令として厳格に分離する」。これが防御の極意です。

正しい実装パターン

`Parameters.AddWithValue` を使うことで、データベースエンジンに対して「この値は単なる文字列(あるいは数値)であり、決して実行してはいけない」と明示的に伝えることができます。

.net
Imports System.Data.SqlClient

Public Sub GetUserInfo(ByVal inputName As String)
‘ 接続文字列(環境に合わせて変更してください)
Dim connString As String = “Server=myServer;Database=myDB;Trusted_Connection=True;”

Using conn As New SqlConnection(connString)
‘ 値を直接埋め込むのではなく、@マーク付きのプレースホルダーを使う
Dim sql As String = “SELECT FROM Users WHERE UserName = @UserName”

Using cmd As New SqlCommand(sql, conn)
‘ ここで安全に値を代入する
‘ 型を意識することがプロへの第一歩です
cmd.Parameters.AddWithValue(“@UserName”, inputName)

conn.Open()
‘ あとは実行するだけ。これでSQLインジェクションは完全に封じられます
Using reader = cmd.ExecuteReader()
‘ データの読み込み処理…
End Using
End Using
End Using
End Sub

3. 「動的SQL構築」という禁じ手への対処法

「検索条件が複数あって、WHERE句が動的に変わる場合はどうするの?」という疑問を持つ方は鋭いですね。

ここでやりがちなのが、`If`文でSQL文字列を連結し続ける方法です。これもまたバグと脆弱性の温床になります。動的SQLが必要な場合、「パラメータリストを管理する設計」を取り入れるのがプロの作法です。

安全な動的SQLの構築法(考え方)

1. SQLのひな形を作る。
2. 条件に応じて、`List(Of SqlParameter)` にパラメータを追加していく。
3. 最後にコマンドの `Parameters` コレクションにすべて流し込む。

.net
‘ 条件に合わせてSQLとパラメータを構築する例
Dim sql As New StringBuilder(“SELECT FROM Users WHERE 1=1″)
Dim params As New List(Of SqlParameter)

If Not String.IsNullOrEmpty(txtSearchName.Text) Then
sql.Append(” AND UserName LIKE @Name”)
params.Add(New SqlParameter(“@Name”, “%” & txtSearchName.Text & “%”))
End If

‘ これをSqlCommandに適用すれば、どんなに条件が増えても常に安全!

4. まとめ:今日から意識すべき「3つの心得」

1. 文字列の連結でSQLを作るな: どんな理由があっても、SQL文の中に変数を `&` で繋ぐのは禁止です。
2. パラメータ化の力を信じろ: `AddWithValue` は単なる便利機能ではありません。あなたのアプリケーションを守る盾です。
3. Using句でリソースを解放しろ: データベース接続は「重い」資源です。`Using` で確実に閉じることで、メモリリークや接続過多を防ぐのがプロの嗜みです。

最後に:あなたへのメッセージ

プログラミングの学習において、セキュリティは「後回しにしてもいいオプション」ではありません。「コードを書くことそのものに組み込まれるべき作法」です。

今回紹介したパラメータ化クエリさえ押さえておけば、VB.NETでのデータベース操作における「最も大きな落とし穴」を回避できます。ここをクリアしたあなたは、もう「マクロの記録」で満足していた頃とは違う、一歩上のエンジニアです。

自信を持って、堅牢で美しいコードを書き続けてくださいね。応援しています!

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