FE EXAM

SQLインジェクション(SQL注入)

入力欄に不正なSQLを注入してデータベースを不正操作する攻撃。

INTERACTIVE VISUALIZATION
攻撃者
データベース
対策
フェーズ
idle
SQL改ざん
なし
認証
保護中
シナリオ
ステップ1 / 6
STEP 1/6ログイン画面(攻撃前)ログイン画面には「ID」と「パスワード」の入力欄があります。Webアプリは入力された値を使ってデータベース(=データの保管庫)に「この人は登録されている?」と問い合わせます。その問い合わせ言語が SQL です。まだ何も入力されていない状態です。
攻撃者不正な入力ログイン入力欄ID:(未入力)PW:(未入力)データベースusers表SQL実行されるSQL:SELECT * FROM users WHERE id = '?' AND pass = '?'
注入のしくみ
想定: SELECT * FROM users WHERE id = '入力' AND pass = '入力'
入力: ' OR '1'='1
結果: ... WHERE id = '' OR '1'='1' AND pass = '...' ← 常に真
対策: WHERE id = ? AND pass = ? ← 値は別枠(攻撃失敗)
解説

📌
SQLインジェクションとは

攻撃者入力欄' OR '1'='1DB不正なSQLがDBに届く

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に溶け込んで意味が変わる瞬間を見てください。

🛡️
対策(プリペアドステートメント)

WHERE id = ? AND pass = ?値(データ)値(データ)

根本的な対策はプリペアドステートメント(プレースホルダ)です。これは SQLの骨組みを先に固定し、入力値はあとから ? の位置にはめ込む方式です。値は「ただのデータ」として扱われ、SQLの命令としては絶対に解釈されません。

穴埋めプリントに例えると分かりやすいです。問題文(SQLの骨組み)は印刷済みで動かせず、解答欄(?)に書いた文字は答えとしてしか読まれません。たとえ ' OR '1'='1 を書いても、まるごと一つの「文字列」として比較されるだけなので攻撃は成立しません。

補助的な対策には次のものもあります。
エスケープ処理' など特別な意味を持つ記号を無害な表記に置き換える
入力値検証:想定外の文字や長さの入力をはじく
権限の最小化:アプリが使うDBアカウントの権限を必要最小限にして被害を抑える

🔍
なぜ攻撃が成立するのか

危険: "WHERE id = '" + 入力 + "'"命令文と値が同じ文字列に混ざっている安全: "WHERE id = ?" → ? に値を別渡し命令文は固定、値は後から「データ」として追加【根本原因】命令と値の境界があいまいなこと

SQLインジェクションが成立する根本原因は、「命令文(SQL)」と「ユーザーが入力したデータ(値)」の境界をプログラムが区別できていない点にあります。普通のプログラムでは、入力された文字列をSQL命令の一部として貼り付けているので、入力に '(シングルクォート)などの記号が混ざると意味が変わってしまいます。

料理の注文で例えると、「オーダー票に注文客が勝手に注釈を書き込んで、厨房がそのまま読んでしまう」状況です。本来は「ラーメン」と書くべきところに「ラーメン、ただし全品無料で」と書き込まれても気づかず実行してしまいます。

プリペアドステートメント(プレースホルダ)はこの問題を「命令文を先に固定し、値は後から別の経路で渡す」という設計で解決します。どれだけ奇妙な文字列が入力されても、それは「答えを書く欄に書かれた文字」として扱われ、命令として解釈されません。上のツールのdefenseステップでこの違いを確認してください。

⚠️
被害の種類と影響

攻撃の種類何をされるか被害の深刻さ
認証突破ログインなしで管理画面に入られる★★★
情報漏えいユーザー一覧・パスワード・個人情報が盗まれる★★★
データ改ざんDBの内容を書き換えられる(価格変更など)★★★
データ削除DROP TABLE などでDB全体を消される★★★

SQLインジェクションの被害は「読む・書く・消す・認証をすり抜ける」の4方向すべてに及びます。単なる情報漏えいにとどまらず、DBごと消去されたり、価格やポイントを書き換えられたりする恐れもあります。

特に個人情報の漏えいは法律(個人情報保護法)上の問題にもなります。攻撃が1件でも成功すると、数万件のユーザー情報が一度に流出するケースが多く、企業の信頼が大きく損なわれます。このため、SQLインジェクションはWebアプリの脆弱性(=セキュリティの弱点)のなかで最も警戒すべき攻撃の一つとされています。

📌
SQLインジェクションが脅かすセキュリティ要素

情報セキュリティの3要素(CIA)とSQLインジェクション機密性情報を漏らさない← 漏えいで破られる完全性改ざんさせない← 書き換えで破られる可用性使えること主な標的ではないSQLiは機密性・完全性の両方を脅かす(DoS攻撃は可用性が主な標的)

情報セキュリティでは、守るべき性質をCIA(=機密性・完全性・可用性の頭文字)と呼びます。SQLインジェクションが特に脅かすのは機密性完全性の2つです。

なぜ機密性が破られるのか:攻撃者がSQLを書き換えてユーザー一覧をまるごと取り出せてしまうため、本来見せてはいけない情報が漏えいします。
なぜ完全性が破られるのか:同様にSQLを書き換えてデータを更新・削除できるため、DBの内容が正しい状態に保てなくなります。

一方、DoS攻撃(=大量のアクセスでサービスを止める攻撃)が主に脅かすのは可用性(使えること)です。攻撃の種類によって「どの性質が狙われるか」が違うため、それぞれの対策も異なります。SQLインジェクションにはプリペアドステートメントが有効ですが、DoSにはアクセス制限や負荷分散が必要で、パスワード強化は両方に対してほぼ効果がありません。

📋
Webアプリ攻撃の見分け方

攻撃注入する場所狙われるもの根本対策
SQLインジェクションフォーム入力欄データベースプリペアドステートメント
XSSコメント欄など閲覧者のブラウザエスケープ処理
バッファオーバーフロー入力データの長さプログラムのメモリ境界チェック
DoS攻撃ネットワーク通信サーバの処理能力レート制限・負荷分散

よく似た名前の攻撃を混同しないために、「どこに何を注入し、何が狙われるか」で整理するのが近道です。

SQLインジェクションはフォームから不正なSQL命令をデータベースに送り込む攻撃です。XSSは悪意のスクリプトをページに埋め込んで閲覧者のブラウザで動かす攻撃です。バッファオーバーフローは入力の長さでメモリを壊す攻撃です。いずれも「入力を検証せずそのまま使う」という共通の弱点から生まれます。

対策は攻撃ごとに異なります。SQLインジェクション→プリペアドステートメント、XSS→エスケープ処理、バッファオーバーフロー→境界チェックと、攻撃の種類と対策をセットで覚えておくと、問題文で「どの攻撃か」を見分けるときに役立ちます。

練習問題

🎯
基本情報技術者 練習問題

Q1.SQLインジェクションの説明として最も適切なものはどれか。
A.入力欄に不正なSQL文を注入し、データベースを不正に操作する攻撃
B.通信を盗聴して暗号鍵を割り出す攻撃
C.大量のパケットを送りつけてサーバを停止させる攻撃
D.メールに偽のリンクを貼り個人情報を入力させる攻撃
Q2.ログイン画面のID欄に " ' OR '1'='1 " を入力すると認証を突破できることがある。その理由として正しいものはどれか。
A.入力文字数が長すぎてサーバが処理を諦めるから
B.入力がそのままSQLに連結され、常に真になる条件が追加されるから
C.パスワードが暗号化されずに保存されているから
D.ブラウザがクッキーを自動送信するから
Q3.SQLインジェクションの根本的な対策として最も適切なものはどれか。
A.パスワードを定期的に変更する
B.通信をSSL/TLSで暗号化する
C.プリペアドステートメント(プレースホルダ)を使い、値をSQLの命令と分離する
D.サーバのOSを最新版にする

関連コンテンツ