SQLインジェクション(SQLi)とは、悪意のあるSQLコードを脆弱なウェブアプリケーションに注入するサイバー攻撃です。これにより攻撃者はデータベースクエリに干渉し、操作することで、サーバーへの不正アクセスを可能にします。コマンドの内容によっては、SQLインジェクション攻撃が成功すると甚大な被害が生じ、企業の収益や評判の損失につながる可能性があります。
SQLインジェクションは、影響が大きく、サーバーやアプリケーションを特定・悪用する方法も複数あることから、代表的な脆弱性の1つです。しかし、開発者たちはSQLi攻撃を検知・防御するために、さまざまな改善を進めてきました。
SQLインジェクションの仕組みとは?
構造化クエリ言語(SQL)は、データベースへのアクセスや操作に使われる標準化言語で、ユーザーごとにカスタマイズされたデータビューを構築できます。アプリケーションとコードが適切にサニタイズされていない場合、ウェブサイトやアプリケーションの入力欄やフォームフィールドに悪意のあるコードが注入される可能性があります。
SQLインジェクションは、攻撃者がユーザー名やパスワードの入力欄、検索バーなどの安全でない入力フィールドを特定し、悪意のあるSQLクエリを挿入、つまり「注入」することで発生します。クエリはバックエンドのデータベースに送信され、データベースはそのコードを正当なリクエストとして受け入れ、要求者に情報を返します。
SQLi攻撃が成功すると、不正アクセスや認証情報などの機密情報の取得、データの追加・削除といった操作、さらにはファイルやフォルダーの削除が可能になります。
- 認証情報を盗む:攻撃者はSQLiクエリを使ってユーザー名やパスワードにアクセスし、盗み出すことができます。
- ウェブサイトやアプリケーションにアクセスする:ユーザー名やパスワードのログインフィールドは、SQLクエリによって回避できます。たとえば、「OR 1=1 ——をユーザー名とパスワードのフィールドに入力します。このコードにより、アプリケーションは常に真となるクエリを実行するため、攻撃者は正規ユーザーになりすましてアプリケーションにアクセスできます。
- データを改変する:SQLインジェクションに対して脆弱なアプリケーションでは、攻撃者がデータベース内のデータにアクセスでき、健康情報や金融情報などの機密情報も対象になります。SQLiの悪用によって高い権限を得た攻撃者は、データの追加、変更、削除を実行できます。
SQLインジェクションにはいくつかの形態があり、近年の歴史において最も悪用されてきた脆弱性の1つです。しかし、アプリケーションコードのエラーを発見し、悪用を防ぐ取り組みも大きく進展しています。
SQLインジェクション攻撃の種類
SQLインジェクション攻撃には多くの形態があります。エラーベース、ユニオンベース、ブラインドSQLiといった一般的な種類から、比較的まれな帯域外攻撃まで存在します。
- エラーベースSQLインジェクション:エラーベースSQLiでは、データベースが出力するエラーメッセージを分析し、データベースに関する情報を収集します。場合によっては、エラーメッセージが攻撃者に貴重な手がかりを与え、脆弱なデータベースの列挙を助けることがあります。
- ユニオンベース攻撃:ユニオンベースSQLiは、SQLのUNION演算子を使って複数のSELECT文の結果を結合するSQLインジェクション技法です。ユニオンベース攻撃では、異なるデータベーステーブルのデータを1つの結果にまとめて取得できます。
- ブラインドSQLインジェクション:ブラインドSQLiは、エラーベース攻撃やユニオンベース攻撃よりも悪用が難しくなります。これは、データが送信されず、試行した攻撃の結果を確認できないことが一因です(そのため「ブラインド」と呼ばれます)。代わりに、ペイロードを送信してアプリケーションの応答を観察し、データベースとやり取りします。
これらのペイロードには、時間ベースのものとブールベースのものがあります。時間ベースのブラインドSQLi攻撃は時間の遅延を発生させようとする一方、ブールベース攻撃はアプリケーションのHTTP応答を変化させます。 - 帯域外SQLi:帯域外SQLiは他の種類よりも一般的ではなく、データベースサーバーの特定の機能が有効になっている場合にのみ機能します。帯域外攻撃は、データベースクエリやエラーメッセージ、HTTP応答に依存しません。代わりに、サーバーにDNSまたはHTTPリクエストを生成させ、攻撃者が管理するリモートエンドポイントへアプリケーションからデータを送信させます。
悪用されるSQLインジェクションの種類にかかわらず、目的は同じです。アプリケーションへの不正アクセスを獲得し、有用だと判断したデータや、最大の影響をもたらし得るデータを外部へ持ち出すことです。これまで私たちは皆、SQLインジェクションに対して脆弱なデータベースが原因となる、1件または複数のデータ侵害の被害に遭ってきました。
攻撃者がSQLインジェクションの脆弱性を悪用する3つの事例
過去、SQLインジェクションは非常に広く使われていました。一時期は、ウェブアプリケーションの脆弱性をまとめたOWASP Top 10で1位になったこともあります。これは、ほとんどのアプリケーションでSQLインジェクションの脆弱性が見つかっていたにもかかわらず、開発者がサニタイズ手法などのベストプラクティスを使っていなかったためです。その結果、Heartland Payment Systems、Sony Pictures、Equifaxなどを含む複数の大規模なデータ侵害が発生しました。
- Heartland Payment Systems:2008年、攻撃者はログインページにSQLインジェクションの脆弱性を発見しました。そこで、次のような悪意のあるSQLコードをユーザー「OR 1=1 –ユーザー名とパスワードのフィールドに入力しました。データベースで処理されると、これらのクエリは真となり、アクセスが許可されます。攻撃者は社会保障番号などの機密性の高いユーザーデータを盗み、それを使って独自のクレジットカードを作成しました。
- Sony Pictures:LulzSecとして知られるハッカー集団がSony Picturesのウェブサイトに侵入し、100万人を超える人々の暗号化されていない個人情報を保存したデータベースを流出させました。同集団は、望むなら「情報を最後の一片まですべて盗む」こともできたと主張しています。ペイロードがウェブサイトのどこで実行されたかによっては、同集団はユーザーデータを盗むために、次のような入力を送信したと考えられます。「UNION SELECT username, password FROM users–このコマンドは、usersというデータベーステーブルの内容と、usernameおよびpasswordという2つの列を取得します。
- Equifax:2017年5月、攻撃者はEquifaxが所有するアプリケーションに脆弱性を発見し、リモートからコマンドを実行できるようにしました。その後、この脆弱性を悪用して細工したSQLコマンドをサーバーに送り、約1億5,000万人の個人データにアクセスしました。これは史上最大規模のデータ侵害の1つとなりました。
SQLインジェクションは組織に甚大な被害をもたらす可能性があります。しかし、先回りして脆弱性を発見し、悪意ある攻撃者に悪用される前に対処すれば、こうした事態を防げます。
ウェブサイトがSQLインジェクションに対して脆弱であることを示す一般的な兆候
SQLインジェクションの脆弱性を探す際には、脆弱性スキャナーなど、さまざまなツールや技法を活用できます。侵入テストなどの評価を実施したり、コードレビューを行ったりすることも可能です。これらのツールには熟練した専門家が必要ですが、ほかにも確認できる点がいくつかあります。
ウェブサイトが脆弱である可能性を示す一般的な兆候には、次のようなものがあります。
- データベース情報を含むエラーメッセージ:フォームや検索バーにシングルクォートまたはアポストロフィ( ‘ )などの特定の文字を入力すると、アプリケーションにSQLの種類やバージョン、列やテーブルの情報、SQLクエリの一部など、SQLデータベースの情報を含むエラーメッセージが表示されます。
- 予期しない挙動:入力フィールドに特定の文字を入力すると、大量のデータが表示される、ウェブサイトがクラッシュするなど、アプリケーションが予期しない結果を返すことがあります。
- データベースクエリ数が異常に多い:データベースのアクティビティを監視していると、ユーザー入力やクエリが突然急増したり、データにアクセスまたは変更されたように見えたりすることがあります。これは、誰かが脆弱性を悪用しようとしていることが原因かもしれません。
- 承認なしのデータ操作:明らかなユーザー操作がないにもかかわらず、データベース内の機密データが変更されたり、アクセスされたりしているように見えます。
検索バーやログイン画面などのウェブサイトの入力フィールド、URLパラメーター、さらにはデータベースを直接対象に、「” ‘ OR ‘1=’1 ”」のような単純なSQLインジェクション文字列を手動で入力し、予期しない挙動がないか確認するだけでも、SQLiの脆弱性を検出できる場合があります。
ウェブアプリケーションでSQLインジェクションを防ぐ3つのヒント
時間の経過とともに、ウェブアプリケーションのセキュリティは大きく向上しました。開発者はSQLインジェクションの脆弱性をより深く認識し、さまざまな防止策を実装するようになっています。防止策には、入力値の検証、ウェブアプリケーションファイアウォール、パラメーター化クエリなどがあります。
- 入力をサニタイズする:ユーザー入力を受け付け、データベースとやり取りするアプリケーションのすべての領域を定期的に点検・監視します。悪意のあるコードの使用を防ぐため、安全でない文字を削除して入力を削除または「サニタイズ」するようにしてください。有効な入力を決める許可リストを作成し、不審な入力はすべて拒否します。
- ウェブアプリケーションファイアウォールを導入する:SQLインジェクションなどの一般的な攻撃を検出・ブロックするため、ウェブアプリケーションファイアウォール(「WAF」)を導入します。WAFはウェブトラフィックを監視し、異常な活動がないか確認します。ファイアウォールは、SQLiに特徴的な通常とは異なるリクエストやパターンをITチームに警告できます。
- パラメーター化クエリを使用する:パラメーター化クエリまたはプリペアドステートメントでは、値の代わりにパラメーターのプレースホルダーを使い、SQLロジックと渡されるデータを分離します。その結果、データベースは入力を実行可能なコードではなくデータとして扱います。
これらの対策を講じ、定期的なセキュリティチェックと侵入テストを実施することで、アプリケーションがSQLインジェクションにさらされるリスクを大幅に低減できます。こうした防止策によってSQLインジェクションは発見・悪用が難しくなり、OWASP Top 10での順位も1位から3位に下がりました。
SQLインジェクション攻撃を防ぐためのヒントやオープンソースツールの一覧などについては、こちらの記事をチェックしてください。
よくある質問
SQLインジェクションに関するよくある質問を紹介します。
- すべてのSQLバージョンがSQLインジェクションに対して脆弱ですか?
はい。クエリの構文は異なる場合がありますが、MySQL、Oracle、PostgreSQL、NoSQLなど、すべてのSQLデータベースがSQLインジェクションに対して脆弱になる可能性があります。 - 影響を受けるアプリケーションは?
適切な保護対策なしにデータベースとやり取りするウェブサイトやアプリケーションは、SQLi攻撃の対象となり得ます。ソーシャルメディア、アンケート、検索アプリ、レポート生成アプリケーションなど、データを利用するアプリケーションが該当します。 - SQLインジェクションをテストするにはどうすればよいですか?
複数のツールやスキャナーで、ウェブアプリケーションのあらゆる脆弱性をテストできます。ただし、すべてのアプリケーションの入力ポイントにSQLペイロードを挿入して、手動でテストすることも可能です。アプリケーションの入力ポイントには、フォーラム、コメント欄、ログインページなど、ユーザーが入力する場所が含まれます。
最良の結果を得るには、アプリケーションの侵入テストを専門とし、アプリケーションの定期的なテストを実施する企業に依頼してください。
まとめ:SQLインジェクションは古い脅威だが、依然として危険
SQLインジェクション攻撃は10年前、あるいは20年前ほど一般的ではありませんが、発見されて悪用されれば甚大な被害をもたらす脆弱性であることに変わりはありません。組織はSQLiの脆弱性を防ぐため、安全なコーディング技法を活用し、アプリケーションを定期的にテストすべきです。
SQLインジェクションが重大な問題を引き起こす実例を見るには、セキュリティ研究者がSQLiを使ってTSAの検査を回避した方法を紹介する動画をご覧ください。





