入力欄に不正なSQLを注入してデータベースを不正操作する攻撃。
SQLインジェクションとは、Webアプリの入力欄に 不正なSQL(=データベースへの命令文)の断片を注入し、本来の問い合わせの意味を書き換えてデータベースを不正に操作する攻撃です。「インジェクション」は英語で「注入」という意味です。
身近な例で考えると、受付の用紙に名前を書く欄へ「名前のあとに勝手な命令文」を書き込むようなものです。受付係が用紙の内容をそのまま声に出して読み上げてしまうと、書いた命令まで実行されてしまいます。プログラムが入力を「ただの文字」ではなく「命令の一部」として扱ってしまうのが原因です。
上のツールで▶ボタンを押すと、攻撃者の入力がそのままSQLに連結され、認証が突破される流れと、対策によって攻撃が失敗する様子を確認できます。
脆弱なプログラムは、ログイン処理でこんなSQLを「文字を貼り合わせて」組み立てます。入力をそのまま連結するのが弱点です。
SELECT * FROM users
WHERE id = '[入力]' AND pass = '[入力]'
ID欄に ' OR '1'='1 を入れると、次の順で攻撃が成立します。
・① 文字列を閉じる:先頭の ' が、id の文字列を途中で終わらせる
・② 条件を追加する:続く OR '1'='1' が新しい条件として混入する
・③ 常に真になる:「1は1と等しい」は必ず正しいので、OR でつながった条件全体が真になる
・④ 認証突破:パスワードに関係なく全ユーザーが該当し、ログインや情報の抜き取りが成立する
この手口は認証突破だけでなく、データの読み出し・改ざん・削除にも応用されます。上のツールのbuildステップで、入力がSQLに溶け込んで意味が変わる瞬間を見てください。
根本的な対策はプリペアドステートメント(プレースホルダ)です。これは SQLの骨組みを先に固定し、入力値はあとから ? の位置にはめ込む方式です。値は「ただのデータ」として扱われ、SQLの命令としては絶対に解釈されません。
穴埋めプリントに例えると分かりやすいです。問題文(SQLの骨組み)は印刷済みで動かせず、解答欄(?)に書いた文字は答えとしてしか読まれません。たとえ ' OR '1'='1 を書いても、まるごと一つの「文字列」として比較されるだけなので攻撃は成立しません。
補助的な対策には次のものもあります。
・エスケープ処理:' など特別な意味を持つ記号を無害な表記に置き換える
・入力値検証:想定外の文字や長さの入力をはじく
・権限の最小化:アプリが使うDBアカウントの権限を必要最小限にして被害を抑える
SQLインジェクションが成立する根本原因は、「命令文(SQL)」と「ユーザーが入力したデータ(値)」の境界をプログラムが区別できていない点にあります。普通のプログラムでは、入力された文字列をSQL命令の一部として貼り付けているので、入力に '(シングルクォート)などの記号が混ざると意味が変わってしまいます。
料理の注文で例えると、「オーダー票に注文客が勝手に注釈を書き込んで、厨房がそのまま読んでしまう」状況です。本来は「ラーメン」と書くべきところに「ラーメン、ただし全品無料で」と書き込まれても気づかず実行してしまいます。
プリペアドステートメント(プレースホルダ)はこの問題を「命令文を先に固定し、値は後から別の経路で渡す」という設計で解決します。どれだけ奇妙な文字列が入力されても、それは「答えを書く欄に書かれた文字」として扱われ、命令として解釈されません。上のツールのdefenseステップでこの違いを確認してください。
| 攻撃の種類 | 何をされるか | 被害の深刻さ |
|---|---|---|
| 認証突破 | ログインなしで管理画面に入られる | ★★★ |
| 情報漏えい | ユーザー一覧・パスワード・個人情報が盗まれる | ★★★ |
| データ改ざん | DBの内容を書き換えられる(価格変更など) | ★★★ |
| データ削除 | DROP TABLE などでDB全体を消される | ★★★ |
SQLインジェクションの被害は「読む・書く・消す・認証をすり抜ける」の4方向すべてに及びます。単なる情報漏えいにとどまらず、DBごと消去されたり、価格やポイントを書き換えられたりする恐れもあります。
特に個人情報の漏えいは法律(個人情報保護法)上の問題にもなります。攻撃が1件でも成功すると、数万件のユーザー情報が一度に流出するケースが多く、企業の信頼が大きく損なわれます。このため、SQLインジェクションはWebアプリの脆弱性(=セキュリティの弱点)のなかで最も警戒すべき攻撃の一つとされています。
情報セキュリティでは、守るべき性質をCIA(=機密性・完全性・可用性の頭文字)と呼びます。SQLインジェクションが特に脅かすのは機密性と完全性の2つです。
なぜ機密性が破られるのか:攻撃者がSQLを書き換えてユーザー一覧をまるごと取り出せてしまうため、本来見せてはいけない情報が漏えいします。
なぜ完全性が破られるのか:同様にSQLを書き換えてデータを更新・削除できるため、DBの内容が正しい状態に保てなくなります。
一方、DoS攻撃(=大量のアクセスでサービスを止める攻撃)が主に脅かすのは可用性(使えること)です。攻撃の種類によって「どの性質が狙われるか」が違うため、それぞれの対策も異なります。SQLインジェクションにはプリペアドステートメントが有効ですが、DoSにはアクセス制限や負荷分散が必要で、パスワード強化は両方に対してほぼ効果がありません。
| 攻撃 | 注入する場所 | 狙われるもの | 根本対策 |
|---|---|---|---|
| SQLインジェクション | フォーム入力欄 | データベース | プリペアドステートメント |
| XSS | コメント欄など | 閲覧者のブラウザ | エスケープ処理 |
| バッファオーバーフロー | 入力データの長さ | プログラムのメモリ | 境界チェック |
| DoS攻撃 | ネットワーク通信 | サーバの処理能力 | レート制限・負荷分散 |
よく似た名前の攻撃を混同しないために、「どこに何を注入し、何が狙われるか」で整理するのが近道です。
SQLインジェクションはフォームから不正なSQL命令をデータベースに送り込む攻撃です。XSSは悪意のスクリプトをページに埋め込んで閲覧者のブラウザで動かす攻撃です。バッファオーバーフローは入力の長さでメモリを壊す攻撃です。いずれも「入力を検証せずそのまま使う」という共通の弱点から生まれます。
対策は攻撃ごとに異なります。SQLインジェクション→プリペアドステートメント、XSS→エスケープ処理、バッファオーバーフロー→境界チェックと、攻撃の種類と対策をセットで覚えておくと、問題文で「どの攻撃か」を見分けるときに役立ちます。