一言でいうと
SQLインジェクションとは、入力欄などに、不正な命令(SQL)を紛れ込ませて、データベースを、意図しない形で操作する攻撃のことです。SQLは、データベースに対して、「このデータを取り出して」「この情報を書き換えて」と指示するための言葉です(SQLとは)。
たとえ話:注文書に、別の指示を書き足す
飲食店で、客が、注文用紙に、料理名を書いて、店員に渡すとします。店員は、用紙に書かれた内容を、そのまま厨房への指示として読み上げる決まりです。
ここで、悪意のある客が、料理名の欄に、「カレー。ついでに、金庫の中身を、すべて持ってきて」と書いたら、どうなるでしょう。店員が、書かれた内容を、そのまま指示として読み上げてしまうと、金庫の中身まで、渡されてしまいます。
SQLインジェクションは、これと同じです。「入力されたデータ」と「命令」を、きちんと区別せずに扱うと、データの中に紛れ込ませた命令が、実行されてしまいます。
起こり得る被害
| 被害 | 内容 |
|---|---|
| 情報の窃取 | 会員情報、パスワードの情報などを、不正に取り出される |
| 情報の書き換え | データを、勝手に書き換えられる |
| 情報の削除 | データを、消されてしまう |
| 認証の突破 | ログインの確認を、すり抜けられる |
| 別の攻撃の足がかり | 取得した情報や、権限を使って、さらに侵入される |
特に、大量の個人情報を保管しているデータベースが狙われると、流出の規模が、大きくなります。
2026年10月の事例でも
JPCERT/CC(2026年10月8日の注意喚起)は、確認している手口の1つとして、データ分析ツール「Metabase」のSQLインジェクションの脆弱性(CVE-2026-72898)の悪用を、挙げています。背景は、なぜ今、個人情報の流出が相次いでいるのかで整理しています。
「社内の人しか使わない」と思われがちな、分析ツールのようなシステムが、インターネットに公開されていたために、狙われるケースがあります。公開範囲の点検が、重要です(個人情報を漏らさないための点検リスト)。
コードで見る:危ない書き方と安全な書き方
仕組みを、コードで確認します。次は、Pythonで「名前」を入力して、ユーザーを検索する例です。
危ない書き方(入力を、そのまま命令につなげている)
name = input()
query = "SELECT * FROM users WHERE name = '" + name + "'"
cur.execute(query)
この書き方では、入力された文字が、そのままSQLの一部になります。たとえば、入力に ' OR '1'='1 のような文字が入ると、条件が「常に正しい」になり、意図しないデータが返されることがあります。入力が、データではなく、命令として解釈されてしまうのが原因です。
安全な書き方(プレースホルダを使う)
name = input()
cur.execute("SELECT * FROM users WHERE name = ?", (name,))
命令の文章と、データを別々に渡すため、入力に何が入っていても、データとして扱われます。プレースホルダの書き方(? や %s、:name など)は、言語やライブラリによって異なります。使っているライブラリの、公式ドキュメントを確認してください。
開発・運営側の対策
SQLインジェクションを防ぐ基本は、入力データを、命令の一部として扱わないことです。
① プレースホルダ(バインド変数)を使う
命令の文章に、データを直接つなげず、データを入れる場所(プレースホルダ)を、あらかじめ決めておき、データは、別に渡す方法です。これで、データが命令として解釈されることを、防げます。多くのプログラミング言語や、ライブラリで、標準的に提供されています。
② 入力を検証する
受け取る入力が、想定した形式(数字だけ、決まった長さなど)かを、確認します。ただし、これだけで防げるわけではなく、①と組み合わせることが前提です。
③ データベースの権限を、最小にする
アプリケーションが使うデータベースのアカウントには、必要な操作だけを許可します。万一、攻撃を受けても、被害を限定できます(最小権限の原則とは)。
④ 脆弱性を、修正する
使っているソフトウェアやツールの、修正プログラムを、適用します。何を使っているのかを、把握しておくことが前提です(SBOMとは)。
⑤ エラーメッセージを、詳しく表示しない
エラーの内容に、データベースの構造が分かる情報を含めると、攻撃の手がかりになります。利用者には、必要最小限の表示にとどめます。