SQLインジェクション(SQL Injection)

SQLインジェクション(SQL Injection)とは

SQLインジェクションは、リレーショナルデータベース(RDBMS)を持つアプリケーションに対し、意図しないSQL(Structured Query Language)文を注入することで、データベースを不正に操作する攻撃です。

SQLインジェクションの概要

SQLインジェクションは、リレーショナルデータベース(RDBMS)を持つアプリケーションに対し、意図しないSQL(Structured Query Language)文を注入することで、データベースを不正に操作する攻撃です。SQLインジェクションは、その手法や目的によって複数の種類が存在し、サイバー攻撃者の視点で言うと、情報窃取、データ改ざん、脆弱性の調査など多岐にわたります。また、古くから存在する攻撃でありながら、現在もなお、多くの被害が発生していることから、法人組織が特に警戒すべき攻撃の1つと言えます。

リレーショナルデータベースとSQL

SQLインジェクションの解説に入る前に、まず、リレーショナルデータベースとSQLについて説明します。リレーショナルデータベースはアプリケーションのデータを管理するデータベースの一種で、データを表形式で管理します。トランザクション(1つひとつの処理)の信頼性の高さから、多くの業務用アプリケーションで使用されています。

SQLは前述のリレーショナルデータベースを操作するための言語(データベース言語)です。操作は主に3つに大別されており、データベースを構成するためのデータ定義言語(DDL)、データの読出しや更新などを担うデータ操作言語(DML)、権限など各種制御を担うデータ制御言語(DCL)で構成されます。なお、SQLの仕様はISOで規定されています。そのため、リレーショナルデータベースであれば、提供ベンダが異なっていても原則、同じように操作をすることが可能です。

ここで、SQLとリレーショナルデータベースを活用したWebアプリケーションの例を見ていきましょう。ユーザはWebアプリケーションのログイン画面で、ユーザ名とパスワードを入力し、「ログイン」を押下することで、システムにログインを試みます。これをアプリケーション目線で見た場合、下記の画像のような処理が行われます。図1の「SELECT・・・」がSQL文です。リレーショナルデータベースは、そのSQL文を受けて、自身の管理するデータベース上に該当ユーザが存在するか否かの確認を行います。そして、その結果についてSQL文を発行したアプリケーションに返します。アプリケーションはリレーショナルデータベースからの回答をもとに、ログインしようとしたユーザへ、適切なページを提供します。

図1:.SQLとリレーショナルデータベースを活用したWebアプリケーションの例

図1:SQLとリレーショナルデータベースを活用したWebアプリケーションの例

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

さて、ここからは前述のアプリケーションをもとに、SQLインジェクションの基本的な仕組みを説明します。

ある日、サイバー攻撃者が本アプリケーションを発見し、攻撃の標的としました。サイバー攻撃者は、既に正規ユーザ「Ken Sato」が本Webアプリケーション上に存在していることを知っていることとします。サイバー攻撃者はユーザ「Ken Sato」を装って不正ログインを試みます。サイバー攻撃者はログインフォームにて、図2のように文字列を入力しました。これをアプリケーション目線で見た場合、図3のSQL文が生成されます。このSQL文はリレーショナルデータベースにおいて、どのように解釈されるのでしょうか。

図2:悪意あるユーザによる入力の例

図2:サイバー攻撃者による入力の例

図3:「図2」の入力から作成されたSQL文

図3:「図2」の入力から作成されたSQL文

本SQL文を受け取ったリレーショナルデータベースはまず、表USERSのUSER NAMEが「Ken Sato」の行を探します。ユーザ名「Ken Sato」は、既に存在しているため、リレーショナルデータベースは次の検索条件に移ります。ここからが問題になります。

検索条件に沿って、リレーショナルデータベースは、ユーザ名が「Ken Sato」かつ、パスワードが「空欄」もしくは、「'1' = '1'」のユーザを検索します。多くのアプリケーションにおいて、パスワードは必須であることから、今回、パスワードが「空欄」のユーザは見つからなかったとします。しかし、「'1' = '1'」はどうでしょうか。これは、「1」と「1」が、同一であるかを比較する数式となります。この結果は当然、常に成立します。そのため、リレーショナルデータベースは、USER NAMEが「Ken Sato」かつ、PASSWORDが「空欄」もしくは「’1’ = ‘1’」が成り立つユーザが存在すると認識します。結果、データベースサーバは、ユーザ名「Ken Sato」のパスワードを確認することなく、そのユーザ名に紐づく情報を、アプリケーションサーバに回答します。アプリケーションサーバは、その情報を元にログイン成功画面を作成し、サイバー攻撃者のブラウザにレスポンスとして送信します。

図4:SQLインジェクションの手口でデータベースに対し不正な処理を実行させる

図4:SQLインジェクションの手口でデータベースに対し不正な処理を実行させる

これが、基本的なSQLインジェクションの仕組みです。今回、わかりやすい例としてWebアプリケーションのログインを挙げましたが、SQL文を使ったデータベースの操作はアプリケーションの多くの機能で使用されています。そのため、ログイン画面に限らず、アプリケーションの様々な場面において、本攻撃が成立する可能性があります。

SQLインジェクションの種類

SQLインジェクションは、その目的や手口によって複数の種類が存在します。ここではその一部を紹介します。

エラーベースSQLインジェクション

アプリケーションの構成や、脆弱性を探ることを目的に使用されるSQLインジェクションの手法です。アプリケーションに対し、意図的に不正な入力を行うことでエラーを発生させ、そのエラーメッセージを基に標的となるシステムの詳細を探ります。本手法自体による直接的なデータの改ざん、流出の可能性は低いですが、本手法で把握した情報を元に、サイバー攻撃者が、脆弱性を狙った攻撃や、後述の他のSQLインジェクション攻撃を仕掛ける可能性があります。

UNIONインジェクション

SQLの1つであるUNION演算子を使用し、任意のデータを参照することを目的としたSQLインジェクションの手法です。UNION演算子は、複数のSELECT文の結果を統合する演算子です。サイバー攻撃者が、アプリケーションの発行するSELECT文に対し、UNION演算子から始まる新たなSELECT文を追加することで、アプリケーションが意図しないデータを取得することが可能になります。本攻撃が成功した場合、サイバー攻撃者は、任意のデータをデータベースの表レベルで得ることが可能となります。そのため、SQLインジェクションの中でも特に大きな被害につながる手口と言えるでしょう。

ブラインドSQLインジェクション

アプリケーションにSQL文を送信し、その直接的な結果ではなく、挙動の違いを見ることでアプリケーションの構造を探る、SQLインジェクションの手口です。エラーベースSQLインジェクションと同様に、本手法自体による直接的なデータの改ざん、流出の可能性は低いですが、本手法で把握した情報を元に、サイバー攻撃者が脆弱性を狙った攻撃や、他のSQLインジェクション攻撃を仕掛ける可能性があります。

セカンドオーダーSQLインジェクション

サイバー攻撃者が、実行時点では効果のない細工が施されたSQL文をアプリケーションに送信し、タイミングを空けて後から実行をさせるSQLインジェクションの手法です。本手法は、直接的なユーザのアクセスが想定されない環境での実行となることから、最悪の場合、データベースの設定や権限の変更など、データベースレベルでの侵害につながる恐れがあります。

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

昨今のアプリケーションは様々な要素で構成されています。そのため、それらの要素ごとの適切な対策、つまり多層防御が必要となります。ここでは、SQLインジェクションによる被害を防ぐ代表的な対策を紹介します。

データベースレベルでの対策

データベースレベルでの対策としては、データベース上のユーザ権限の適正化が挙げられます。前述の通り、リレーショナルデータベースの操作は3つに大別されており、データベースの構成を担うデータ定義言語(DDL)、データの読出しや更新などを担うデータ操作言語(DML)、権限など各種制御を担うデータ制御言語(DCL)で構成されます。しかし、多くのアプリケーションが通常使うものは、多くの場合、SELECT句などのDMLです。それ以外の操作権限を制限することで、意図しないデータの削除や、設定の変更を防ぐことが可能です。

アプリケーションレベルでの対策

アプリケーションレベルでの対策は多岐にわたります。

●プレースホルダの利用

プレースホルダを使用してSQL文を作成することで、SQLインジェクションを防止することが可能です。プレースホルダは、アプリケーションであらかじめ用意したSQL文に、機械的に入力値を割り当てるものであり、不正な値がアプリケーションのインプットとして提供された場合でも、それらを不正な値とみなし、最終的なSQL文の作成を停止(エラーと判断)します。

●入力値の適切なエスケープ処理

SQL文の中で特殊な意味を持つ記号や文字列をエスケープ処理し、通常の文字列として扱うことで、意図しないリレーショナルデータベースの操作を防ぎます。エスケープの対象としては、「`(シングルクォート)」、「;(セミコロン/意味:当該記号をもってSQL文の最後とみなす)」、「--(2連続のハイフン/意味:当該記号以降をコメントとして扱う)」、「UNION(UNION句/意味:2つ以上のSELECT文の結果を統合する)」などが挙げられます。また、「1」などの数字の場合、それがデータベース上で、「数値」として扱われるのか、「文字」として扱われるか明示的に定義し、適切に変換することが必要です。

●エラーの非表示

アプリケーションが表示するエラーメッセージは、サイバー攻撃者に多くの情報を提供する恐れがあります。「エラーベースSQLインジェクション」にも記載の通り、攻撃者はこれらメッセージを基に、さらなる攻撃を仕掛ける恐れがあります。アプリケーション開発時は、データベースに限らず、システムの内部環境の把握につながるエラーメッセージを直接表示しないことが大切です。

●パッケージシステムへの修正プログラム適用

パッケージシステムをご利用の場合、ベンダから公式に提供される修正プログラムを可能な限り、早めに適用することを推奨します。SQLインジェクションを含む、各種脆弱性からシステムを保護することが可能になります。

ネットワークレベルでの対策

ネットワークレベルでの対策としては、IPS(Intrusion Prevention System)WAF(Webアプリケーションファイアウォール)の活用が挙げられます。IPSはネットワークを監視し、悪意ある通信を検知/ブロックするソリューションです。WAFはWebアプリケーションの保護を担うソリューションであり、Web通信を検査することで、Webアプリケーションの脆弱性を狙った攻撃を検知/ブロックします。

稼働環境全体レベルでの対策

前述の対策後、外部からのペネトレーションテストや脆弱性診断を実施することで、対策の有効性、及び不備を客観的に評価することが可能になります。

まとめ

SQLインジェクションは古くから存在する攻撃でありながら、昨今でも大きな被害につながった事例が数多く確認されています。そのため、今現在も組織が警戒すべき攻撃と言えるでしょう。特に、UNIONインジェクションのような手法が用いられ、実行が成功してしまった場合は、大規模な情報漏洩につながる恐れもあります。しかし、適切な対策を講じることで、その被害を未然に防ぐことが可能です。法人組織のセキュリティ対策としては、前述の多層防御の観点での対策に加え、外部からのペネトレーションテストや脆弱性診断など、安全性の評価を定期的に実施されることを推奨します。

SQLインジェクションについての関連情報

ファイル転送サービスMOVEit File Transferに深刻なSQLインジェクションの脆弱性:影響と対策を解説

ファイル転送サービスMOVEit File Transferにおいて複数のSQLインジェクションの脆弱性が報告されました。本脆弱性による攻撃が既に米国連邦政府機関で確認されていることから、本稿ではその影響と対策について解説します。

トレンドマイクロのソリューション Trend Micro Endpoint Security
(旧称:Trend Cloud One Workload Security)によるSQLインジェクション対策