SQLインジェクションとは?仕組み・由来・対策方法をわかりやすく解説!

Webアプリケーションの開発や運営をしていると、必ず耳にするセキュリティ脆弱性のひとつがSQLインジェクションです。

  • 名前は聞いたことがあるけれど、具体的にどんな攻撃なのかイメージがわかない
  • 実際にどんな被害が起こるのか、どう防げばいいのかがよくわからない

そんな方も多いのではないでしょうか。この記事では、SQLインジェクションの仕組み・効果的な対策方法・クロスサイトスクリプティング(XSS)との違いなどをわかりやすく解説します。ご参考になれば幸いです。

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

「SQL(エスキューエル)」は、データベースを操作するために広く使われている言語です。Webアプリケーションがユーザー情報や商品データを扱うとき、多くの場合このSQLを使ってデータベースとやり取りをします。

しかし、この仕組みを悪用する攻撃手法の一つに「SQLインジェクション(SQL Injection)」があります。

SQLインジェクションは、Webアプリケーションに対して本来意図されていない不正なSQL文を外部から注入(インジェクション)し、データベースを不正に操作する脆弱性攻撃です。

例えば、ログインフォームにユーザー名やパスワードを入力すると、その値はSQL文に組み込まれて認証処理が行われます。通常であれば「ユーザーが入力した情報とデータベースの情報を照合する」だけの動きですが、もしWebアプリケーションが入力値を適切に処理していなければ、攻撃者は不正な文字列を入力することでSQL文の意味を変えることができます。この結果、本来はログインできないはずの人物が不正ログインできてしまったり、データベースに保存されている顧客情報や機密データが漏洩したりする危険性が生じます。さらに、データの改ざん・削除・システム障害といった重大な被害につながるケースも少なくありません。

SQLインジェクションの由来

「SQLインジェクション」という名前は、文字通り「SQL文に外部から不正なコードを注入(Injection)する」ことに由来します。

「インジェクション(Injection)」という言葉は、もともと医学用語で「注射」や「注入」を意味します。セキュリティの分野では、プログラムに対して外部から意図的にデータやコードを流し込み、本来想定していない動作を引き起こす攻撃を指す一般的な表現として使われています。

SQLインジェクションの仕組み

SQLインジェクションの仕組み

SQLインジェクションの仕組みについて、「検索フォームでの例」と「ログイン処理での例」の2つの例を用いて解説します。

検索フォームでの例

通常の検索機能では、次のようなSQL文が使われます。このSQL文は「データベースから、ユーザーの情報を検索する」という指示で、Webサイト上で、ユーザーの情報を絞り込んだり、表示させたりする際に使用されます。

SELECT * FROM users WHERE name = '太郎';

このSQL文は「usersテーブルのname列が'太郎'という入力値に一致するレコードを取得する」という指示です。つまり、ユーザーが入力した名前に一致する情報だけを検索する仕組みです。

もし攻撃者が、次のような入力を検索フォームに与えたとします。

  • ' OR '1'='1

するとSQL文は次のように組み立てられてしまいます(以下のSQL文では太郎の部分が' OR '1'='1に変わっています)。

SELECT * FROM users WHERE name = '' OR '1'='1';

ここでは、条件式の後半にある'1'='1'が常に真(true)になる条件なので、結果的にデータベース内の全ユーザー情報が抽出され、閲覧できるようになってしまいます。

このように「常に真となる条件」を作り出すのは、SQLインジェクション攻撃でよく利用される典型的な手口です。

これが有名なOR 1=1」攻撃の代表例です。

ログイン処理での例

もうひとつ代表的なのがログイン画面を使った攻撃です。通常、ログイン処理では次のようなSQL文が実行されます。

SELECT * FROM users WHERE username = '入力されたユーザー名' AND password = '入力されたパスワード';

ここで攻撃者が以下のような入力をしたとします。

  • ユーザー名: admin
  • パスワード: ' OR '1'='1

すると実際に組み立てられるSQLは次のようになります。

SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';

この場合も、条件式の後半にある'1'='1'が常に真(true)になる条件なので、認証チェックがすり抜けられ、パスワードを知らなくても不正ログインが可能になってしまいます。

「SQLインジェクション」と「クロスサイトスクリプティング」の違いと比較

Webアプリケーションを狙った攻撃の中で、よく名前が挙がるのがSQLインジェクション(SQLi)クロスサイトスクリプティング(XSS)です。両者は「ユーザー入力を悪用する」という点で共通していますが、攻撃の仕組みや対象が異なります。

SQLインジェクションは、Webサイトが利用しているデータベースそのものを直接狙う攻撃です。たとえばECサイトや会員制サービスでは、顧客の氏名・住所・パスワード・クレジットカード情報などがデータベースに保存されています。

攻撃者は、ログインフォームや検索フォームに「不正なSQL文」を入力し、そのままアプリケーションに実行させます。すると本来アクセスできないはずの顧客情報や機密データが引き出されるのです。

そのため被害を受けるのは主にWebサイトの運営者です。運営者のデータベースから情報が抜き取られ、情報漏洩によって企業の信頼失墜・賠償責任・法的処分といった二次的被害が拡大します。

一方、クロスサイトスクリプティングは、Webサイトを経由してユーザー自身を攻撃する手法です。脆弱性のあるWebサイトに罠(悪意のあるスクリプト)が仕掛けられており、利用者がそのページを開くと、攻撃者が用意したコードがユーザーのブラウザ上で実行されます。

その結果、ユーザーのCookieやセッションIDが盗まれたり、偽の入力フォームが表示されてパスワードやクレジットカード番号を入力させられるといった被害が生じます。さらに、攻撃者が用意したフィッシングサイトへ誘導され、知らないうちに個人情報を盗まれてしまうこともあります。

つまり被害を受けるのは主にWebサイトの利用者です。攻撃が成功すると、ユーザーのアカウントが乗っ取られたり、個人情報が不正利用されたりする可能性が高くなります。

両者の違いを表で整理したのが以下になります。

項目SQLインジェクション(SQLi)クロスサイトスクリプティング(XSS)
攻撃の仕組みデータベースに不正なSQL文を注入Webページに不正スクリプトを仕込み、ブラウザで実行
主な攻撃対象Webサイトの運営者Webサイトを利用するユーザー
代表的な被害顧客情報の流出、データ改ざん、システム停止、不正ログインCookie・セッションIDの窃取、アカウント乗っ取り、フィッシング

あわせて読みたい

クロスサイトスクリプティング(XSS)』については下記の記事で詳しく説明しています。興味のある方は下記のリンクからぜひチェックをしてみてください。

SQLインジェクションによって発生する被害

SQLインジェクション攻撃が成功すると、攻撃者はデータベースを自由に操作できる状態になります。その結果、以下のように多岐にわたる深刻な被害が発生する可能性があります。

個人情報・機密情報の漏洩

SQLインジェクションの最も深刻な被害は、データベースに保存されている顧客情報や機密データの流出です。

  • 氏名・住所・電話番号
  • メールアドレス・ログインID・パスワード
  • クレジットカード情報や銀行口座情報

こうした情報が流出すると、不正利用・二次被害(詐欺やスパム、なりすまし被害)につながります。企業にとっては信用失墜や巨額の損害賠償に発展することもあります。

データの改ざん・削除

SQLインジェクションによって、攻撃者は単にデータを閲覧するだけでなく、任意に改ざんや削除することも可能です。

  • 在庫データや価格情報を改ざんして販売システムを混乱させる
  • 顧客アカウントのパスワードを強制的に変更する
  • サービスに必要な重要データを削除してシステム停止に追い込む

これらの行為は直接的にサービスの提供を妨害し、企業活動に大きなダメージを与えます。

認証回避・アカウントの不正利用

SQLインジェクションによって、攻撃者は正規のパスワードを知らなくてもログインできてしまいます。

  • 管理者アカウントへの不正ログイン
  • 他人のアカウントを乗っ取って不正操作
  • 内部情報への不正アクセス

攻撃者が管理者権限を奪った場合、被害はさらに拡大し、システム全体の支配につながる危険性があります。

サーバーの乗っ取り・他システムへの攻撃

一部のデータベース製品では、SQLインジェクションを利用してサーバー上でOSコマンドを実行できてしまうケースもあります。これにより

  • サーバーの完全な乗っ取り
  • マルウェアの設置や外部への攻撃の踏み台化
  • 企業ネットワーク全体への侵入

といった大規模な被害へ発展する恐れがあります。

SQLインジェクションの対策

SQLインジェクションは古くから知られている攻撃手法ですが、適切な対策を行えば防ぐことが可能です。ここでは代表的で効果的な防止策を紹介します。

プレースホルダ(バインド変数)の利用

SQLインジェクション対策として最も有効なのがプレースホルダ(バインド変数)の利用です。

実際の値が入る予定の場所に仮の値や記号(プレースホルダ)を置き、実際の値を後から割り当てます。

プレースホルダを使うと、攻撃者が入力値に不正なSQL文を埋め込んでも「単なる値」として判断されます。その結果、SQL文として実行されてしまうのを防ぐことができます。

あわせて読みたい

プレースホルダ』については下記の記事で詳しく説明しています。興味のある方は下記のリンクからぜひチェックをしてみてください。

入力値の検証と制限

外部からの入力を「無条件に信用しない」ことが鉄則です。WebフォームやAPIから受け取った値に対しては、以下のような検証・制限を行います。

  • 型チェック
    • 数字のみを受け付ける項目 → 数値型にキャスト
  • 文字数の制限
    • 例:ユーザー名は最大50文字まで
  • 利用可能文字種の制限
    • 例:英数字のみ、メールアドレス形式のみなど

これにより、攻撃者が長大な文字列や特殊記号を使ってSQLを壊すことを防げます。

エスケープ処理

どうしても文字列連結でSQLを組み立てざるを得ない場合は、特殊文字をエスケープする必要があります。以下に一例を示します。

  • '''
  • \\\

ただし、これはあくまで補助的な対策であり、プレースホルダの代替にはなりません。

最小権限の原則

SQLインジェクションが万一成功してしまった場合に備えて、被害を最小限にする仕組みも重要です。以下に一例を示します。

  • 読み取り専用の処理 → SELECT権限のみ
  • 更新が不要な場合 → UPDATE・DELETE権限は付与しない

WAF(Web Application Firewall)の利用

アプリ側で完全な対策をするのが理想ですが、追加の安全策としてWAFの導入も有効です。

WAFは典型的なSQLインジェクション攻撃パターン(例:OR 1=1, '--, UNION SELECTなど)を検出してブロックできます。

本記事のまとめ

この記事では『SQLインジェクション』について説明しました。

SQLインジェクションは、古くから知られている危険な攻撃ですが、基本的な対策を守れば防げます。プレースホルダを使った実装や入力値のチェック、最小限の権限設定などを徹底することが重要です。

お読み頂きありがとうございました。

スポンサーリンク