現在の DB エンジン ランキングによると、 Oracle 、MySQL、PostgreSQL、 Microsoft SQL Serverなどのリレーショナル データベース管理システム ( RDBMS ) は、市場で最も人気のあるものの 1 つです。これらは非常に信頼性が高く、データセットの不一致を回避できると考えられているため、数十年にわたってほとんどの企業でデータベースの標準として確立されてきました。
通常、データベース言語の構造化照会言語 (SQL) は、データベース内のデータの照会と編集に使用されます。たとえば、ユーザーはオンライン ショップの製品検索マスクを介してサーバーと通信します。これにより、データベースにクエリが実行され、受信した情報が検索結果として Web ショップに返されます。
このように、データベースに格納されているデータは、クエリに任意のコードを挿入する、いわゆる SQL インジェクション (SQLi) に対して脆弱です。これにより、許可なく情報を読み取ったり、変更したりすることが可能になります。最悪の場合、侵入者はデータベース全体を制御してしまいます。
シンプルで長く愛用できる
この攻撃手法は 1998 年に発見され、それ以来、最も持続的な脅威の 1 つと考えられています。間違ってはいません。 2019 年 3 月、 オンライン ショップ ソフトウェア Magento のギャップが発見され、埋められました。このギャップにより、小売業者のデータベースから顧客データが読み取れるようになりました。 2018年、カナダのインターネットサービスプロバイダーAltimaのウェブサイトでグリッチ(コンピュータプログラムの誤動作を引き起こすソフトウェアまたはプログラミングエラー)が発生した。いわゆるブラインド SQL インジェクションを使用して、広範な顧客データベースにアクセスすることも可能でした (これについては後で詳しく説明します)。
SQL インジェクションがハッカーの間で非常に人気がある理由の 1 つは、SQL インジェクションが非常に単純な攻撃であるためと考えられます。 2018年にラスベガスで開催された第26回DEF CONハッカー会議では、11歳の子供が米国フロリダ州の選挙結果を表示するウェブサイトのコピーをわずか10分でハッキングして操作することができた。 SQLi経由。
一方、防御策はシンプルかつ効果的です。以下ではさまざまなタイプの SQLi について説明し、防御のためのオプションを示します。
SQL インジェクションの種類
SQL インジェクションの種類に関係なく、攻撃者は Web アプリケーションのデータベース クエリに任意の SQL コードを挿入します。これはさまざまな方法で発生する可能性があります。
最も単純な形式の攻撃は、ユーザー入力を通じて発生します。通常、Web アプリケーションはフォーム経由で入力を受け入れます。次に、フロントエンドは入力をバックエンドのデータベースに転送して処理します。 Web アプリケーションが入力をクリーンアップしない場合、挿入された SQL 入力を介してデータベースの内容を削除、コピー、または変更することが可能です。
攻撃者は、Web アプリケーションのクエリに感染するようにCookie を変更することもできます。 Cookie はクライアントのステータス情報をローカル ハード ドライブに保存します。通常、Web アプリケーションは Cookie をロードしてこの情報を処理します。悪意のあるユーザーまたはマルウェアがこれらを変更して、バックエンド データベースに SQL コマンドを挿入する可能性があります。 HTTP ヘッダーなどのサーバー変数を使用しても同じことが可能です。 Web アプリケーションがこの入力をクリーンアップしない場合、任意の SQL を含む偽のヘッダーによってこのコードがデータベースに挿入される可能性があります。
ブラインド SQL インジェクションタイプには、SQLi を積極的に防御しないが、インジェクションの結果を視覚的に表示しない Web アプリケーションに対する攻撃が含まれます。代わりに、明らかな応答が表示されないか、たとえば、SQL クエリの構文が間違っているという一般的なエラー メッセージが表示されます。この場合、ページにはデータが提供されませんが、正規の SQL に挿入された論理ステートメントの結果に応じて、表示は若干異なります。
この方法では、情報は直接識別されるのではなく、一連の真偽クエリを通じてデータベースから抽出されます。この方法は非常に時間がかかると考えられています。ただし、脆弱性と必要な情報が見つかったら、さまざまなツールを使用して攻撃を自動化できます。
二次SQL インジェクション攻撃は、すぐには行動を起こさず、後の時点で行動を起こすため、最も潜行性の高い攻撃の 1 つです。このような悪意があるが、最初は非アクティブな SQL コマンドは、アプリケーションによって正しくコーディングされ、有効な SQL としてデータベースに保存されます。 SQLi から保護されていない可能性があるアプリケーションの別の部分が、保存されている SQL ステートメントを別のコンテキストで実行すると、時間遅延攻撃が開始されます。
単純な SQL インジェクション攻撃の例
ある企業が、顧客が顧客番号を入力することで自分のプロフィールにアクセスできる Web アプリケーションを構築したとします。アプリのフロントエンドは、入力された番号をバックエンドに転送します。データベースはそこで SQL 呼び出しを実行し、結果をアプリケーションに返し、アプリケーションはそれをユーザーに表示します。
そこで、ユーザーはフロントエンドに自分の番号 1234567 を入力します。
バックエンドのクエリは次のようになります。
選択 *
お客様から
WHERE 顧客 ID = ‘1234567’
代わりに、ユーザーが Web フォーム上のフィールドに次の顧客番号を入力したとします。
1234567′; DELETE * 顧客 WHERE ‘1’ = ‘1
バックエンドのデータベースは次の SQL を実行します。
選択 *
お客様から
WHERE customer_id = ‘1234567’;
消去 *
お客様から
WHERE ‘x’ = ‘x’
データベースは、セミコロン (;) で区切られている場合、複数の SQL ステートメントを順番に実行します。入力が一重引用符 (‘) に対してサニタイズされていない場合、攻撃者はテーブル全体を削除する可能性があります。
これは意図的に単純な例ですが、すべての SQLi は同じ原理で動作します。つまり、Web アプリケーションを介した生の入力により、データベース内の任意の SQL コードが実行されます。
火で火を消す
SQLi 攻撃は比較的単純であるため、自動化されるまでに時間はかかりませんでした。 SQLninja、SQLmap、Havij などのツールは、攻撃者と防御者の両方が利用できます。これにより、企業は SQLi に対する Web アプリケーションの脆弱性をテストできるようになります。
たとえば、SQLmap は、MySQL、Oracle、PostgreSQL、Microsoft SQL Server、Microsoft Access、 IBM DB2、SAP MaxDB など、ほぼすべての主要なデータベースをサポートしているため、優れたオプションです。すべての主要なオペレーティング システムで利用でき、Web アプリケーションの最もよく知られたインジェクションの抜け穴を検出します。これにより、入力をクリーンアップするための対策が実際に機能しているかどうかを迅速に判断できます。
SQLインジェクションの検出
SQL インジェクション攻撃を検出するには 2 つの方法があります。 Web アプリケーション ファイアウォール(WAF) は、受信トラフィックに操作的な入力がないかを検査し、必要に応じて、事前定義されたルールに従ってトラフィックをブロックできます。
ただし、この保護手段が常に効果的であるとは限りません。 2022 年末、セキュリティ研究者は、複数のプロバイダーの WAF をバイパスできる新しい SQLi の亜種を発見しました。 (これについては姉妹出版物 CSO で読んでください:「 新しい SQL インジェクション攻撃が WAF を騙す可能性がある」)
データベース自体を監視するという点では、侵入検知システム (IDS) が役立ちます。ネットワークベースの IDS はデータベースへのすべての接続を監視し、不審なアクティビティに対してアラームを発します。ホストベースの IDS は Web サーバーのログ ファイルを監視し、異常を報告します。
SQLインジェクションを防止する
関連するすべての保護対策の包括的かつ詳細な説明は、OWASP のSQL Injection Prevention Cheat Sheetにあります。以下に、最も重要なものを厳選して紹介します。
企業 IT 上のすべての攻撃対象領域の大部分と同様、ここでも同じことが当てはまります。適切なパッチの衛生管理により、多くの問題が解決されます。ハッカーが SQL インジェクションに利用できるアプリケーションとデータベースの脆弱性は定期的に発見され、修正されています。したがって、パッチとアップデートを最新の状態に保つことが重要です。
基本的な保護のためには、すべてのエントリが例外なく実行前にクリーンアップされるように、SQL を介してデータベース アクセスを規制することが重要です。これは、操作を示す異常な文字を許可しないことを意味します。また、エントリが誤ってコマンドとして採用されないように、エスケープ シーケンスなどの手段を使用することをお勧めします。また、すべての入力をコンテキストでフィルタリングすることをお勧めします。たとえば、電話番号には数値のみを入力できるようにする必要があります。いわゆる準備されたステートメントは、攻撃者が別のコマンドを入力した場合でも、クエリの目的が変更されることを防ぎます。
クリーニングを行っても抜け穴が残る場合は、データベース ユーザーのアカウント権限を制限する必要があります。最小限の権限の原則を適用する必要があります。アプリケーションには、そのタスクを実行するのに十分なアクションの範囲があり、それ以上のことはありません。たとえば、Web アプリケーションは読み取りアクセス許可のみを受け取ることができますが、書き込みアクセス許可は受け取ることができません。また、データベース全体を削除する「 DROP TABLES 」などのコマンドも実行できないようにしてください。
ストアド プロシージャ、つまりデータベースに保存された一連のコマンドを 1 回の呼び出しで実行する関数も、完全に不可能ではありませんが、SQLi をより困難にします。 Web アプリケーションがいくつかの SQL クエリを実行するだけでよい場合は、そのためにストアド プロシージャを作成する必要があります。通常、データベース管理者のみがそれらを作成および編集する権限を持っています。多くのデータベースには、攻撃者に知られている可能性がある事前定義されたストアド プロシージャが既に存在することに注意することが重要です。これらは絶対に必要でない限り、削除する必要があります。
ケアは最大の防御です
SQL インジェクションは企業データに対する最も単純な攻撃ベクトルの 1 つであるため、それほど高度ではない攻撃者でもこれを悪用して重大な損害を引き起こす可能性があります。しかし、企業がこの開いた側面を閉じることも同様に簡単です。必要なのは、Web アプリケーションとデータベース間の通信を少し注意して設定し、いくつかの保護措置を実装することだけです。