「SQLインジェクション」は怖くない!あなたのプログラムを「最強の金庫」に変える魔法の呪文
こんにちは!セキュリティの世界へようこそ。
日々、開発の現場でコードを書いていると、「セキュリティ対策をしなさい」と口うるさく言われることはありませんか?でも、専門用語ばかりで何から手を付ければいいのか、正直よくわからないですよね。
今日は、数ある攻撃の中でも「これだけは絶対に防がないといけない!」というSQLインジェクションについて、泥棒の侵入防止に例えてお話しします。難しく考えすぎず、一歩ずつ一緒に学んでいきましょう!
—
1. SQLインジェクションって何?「泥棒の手口」を知ろう
まず、あなたのプログラムを「大事な書類が入っている金庫」だと想像してください。この金庫には、「〇〇さん、書類を見せて」と伝えるための「受付担当(データベース)」がいます。
通常、受付担当はルール通りに動きます。
- ユーザー:「ユーザーIDは『123』だよ」
- 受付:「はい、ID『123』の書類ですね、どうぞ」
ところが、悪意ある人が現れるとこうなります。
- 悪意ある人:「ユーザーIDは『123』! それと、ついでに金庫の中身を全部バラしてね!」
もし受付担当がこの言葉をそのまま信じてしまったら……大変ですよね。これがSQLインジェクションです。「入力されたデータを、命令(コマンド)として実行してしまう」という、プログラムの「お人好し」な隙を突く攻撃なんです。
—
2. 魔法の盾「プリペアドステートメント」
この攻撃を防ぐ最強の手段が、「プリペアドステートメント(準備された命令文)」です。
イメージとしては、受付担当に「あらかじめ決まった形式の書類しか受け取らない」というルールを徹底させることです。
「IDを入れる欄には、数字のデータしか入れないよ。命令文(SQL)はこっちで先に作っておくから、君はそこに数字を流し込むだけにしてね」と約束するんです。これなら、途中で変な命令が混ざり込んでも、受付担当は「これはただの数字じゃない、変な命令だ!」と見抜いて弾いてくれます。
—
3. 実践!言語別の実装パターン
それでは、実際にどう書けばいいのか、主要な言語で見ていきましょう。どれも基本は「命令文のテンプレートを作り、そこに値を流し込む」というスタイルです。
Java (JDBC) の場合
Javaでは `PreparedStatement` を使います。`?`(プレースホルダー)が、データの流し込み口です。
// 1. 命令のテンプレートを先に作る
String sql = “SELECT FROM users WHERE id = ?”;
PreparedStatement pstmt = connection.prepareStatement(sql);
// 2. プレースホルダー(?)に安全なデータを流し込む(これなら命令は実行されない!)
pstmt.setString(1, “123”);
// 3. 実行!
ResultSet rs = pstmt.executeQuery();
Python (psycopg2) の場合
Pythonのライブラリも、実はとても親切に作られています。カンマで値を渡すだけで、ライブラリ側が自動的に「これはただの文字列だよ」と処理してくれます。
プレースホルダーは %s を使うのが一般的です
sql = “SELECT FROM users WHERE id = %s”
user_id = “123”
カンマで区切って渡すことで、ライブラリが安全に処理してくれます
cursor.execute(sql, (user_id,))
Node.js (pg) の場合
Node.jsでも、SQL文の中に直接変数を埋め込まないのが鉄則です。
const query = {
text: ‘SELECT FROM users WHERE id = $1’, // $1 は最初の値を入れる場所
values: [‘123’], // ここに配列として安全な値を渡す
};
const res = await client.query(query);
—
4. なぜ「文字列連結」はダメなの?
一番やってはいけないのが、以下のような書き方です。
// 危険な例:文字列をそのまま繋げると、命令が混入する隙ができる
const sql = “SELECT FROM users WHERE id = ‘” + userInput + “‘”;
これだと、もし `userInput` に `’ OR ‘1’=’1` なんていう魔法のコードが入ってきたら、金庫は「全データ開示」という命令だと勘違いしてしまいます。「変数を使ってSQL文を組み立てない」、これだけ守れば、あなたのプログラムは格段に強固になります!
—
最後に:セキュリティは「習慣」です
「SQLインジェクション対策」と聞くと難しく感じますが、要は「ユーザーからの入力を、直接命令として扱わない」というルールを守るだけです。
最初は少し面倒に感じるかもしれませんが、一度この書き方を身につけてしまえば、それがあなたの「当たり前」になります。家の鍵をかけるのと同じで、無意識に安全なコードを書けるようになれば、あなたはもう立派なセキュリティ意識の高いエンジニアです!
これからも、一緒に賢く、安全な開発ライフを楽しんでいきましょうね!

コメント