セキュリティ用語集: WAF

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

SQL インジェクションは、攻撃者がソフトウェア アプリケーションまたはサイト インターフェイスに SQL コマンドを送信し、ハッキング対象のソフトウェアまたはサービスを提供している可能性のあるデータベース サーバーをターゲットとする一般的なタイプのインジェクションです。

SQL インジェクション攻撃は、攻撃者がデータベースに不正にアクセスし、データを取得、変更、削除したり、場合によってはサーバー全体を危険にさらしたりする可能性があるため、特に危険です。このタイプの攻撃は、ユーザー入力を適切に検証しない Web アプリケーションの不適切なコーディングを利用します。攻撃者は、ログイン フォームなどの入力フィールドに SQL コマンドを挿入または「注入」して、データベース サーバーで実行することで、この脆弱性を悪用します。

SQL インジェクション攻撃の深刻さは、SQL インジェクション攻撃がデータベース コマンドの操作に使用され、攻撃者に認証を回避し、機密データにアクセスし、データベース上で管理操作を実行できるという事実に由来します。場合によっては、攻撃者が SQL インジェクションを使用して組織のシステムに永続的なバックドアを侵入させ、データ セキュリティに長期的な脅威をもたらす可能性があります。

SQL インジェクションの原因とデモンストレーション

SQL インジェクションの脆弱性の主な原因は、データのやり取り中にフロントエンドからバックエンドにデータが渡されるときに厳密な検証が行われないことにあります。これにより、入力データが SQL ステートメントに連結され、SQL クエリの一部として実行される可能性があります。その結果、データベースが侵害され、データの漏洩、削除、さらにはサーバー アクセス全体の侵害につながる可能性があります。

Pikachu トレーニング環境の SQL-Inject モジュールは、この脆弱性を実証できます。システムに登録されているユーザー名を次のアプリケーションの入力フィールドに入力すると、システムは対応する UID と電子メールを返します。

SQLインジェクション_01

このサービスの PHP コードは次のとおりです。バックエンド コードは、フロントエンドから渡された名前パラメータに対してフィルタリングを実行しません。次のように、それをデータベース クエリ ステートメントに直接連結します。

「ユーザー名が '$name' のメンバーから ID、メールを選択」

これにより、SQLインジェクションの脆弱性が発生します。攻撃者は、名前パラメータを通じて悪意のあるSQL文を挿入し、サービスが提供しようとしているもの以外のデータを取得し、システムの機密性を侵害する可能性があります。

if (isset($_GET['submit']) && $_GET['name'] != null) {

// ここでは処理は行われず、直接SELECT文に連結されます

$name = $_GET['name'];

// この変数は文字列型なので、エスケープを考慮する必要があります。

$query = "ユーザー名が '$name' のメンバーから ID、メールを選択";

$result = 実行($link、$query);

(mysqli_num_rows($result) >= 1)の場合{

     ($data = mysqli_fetch_assoc($result)) の間 {

         $id = $data['id'];

         $email = $data['email'];

         $html .= &quot;<p class='notice'>あなたのUID: {$id} <br />あなたのメールアドレスは: {$email}です</p>";

     }

} それ以外 {

     $html .= &quot;<p class='notice'>入力したユーザー名は存在しません。再入力してください。</p>";

}

}

前述のクエリ サービスを例に挙げると、悪意のある SQL インジェクション ペイロード (テスト ' または 1=1#) を入力すると、システムは登録されているすべてのユーザーの UID とメール アドレスを返します。これは、データ漏洩のわかりやすい例です。ハッカーが SQL インジェクションの脆弱性に気付くと、データベースの追加、削除、変更、クエリなどの操作を自由に実行できます。Web シェルを挿入して、サーバー全体をさらに制御する可能性もあります。

SQLインジェクション_02

どうしてこのようなことが起こるのでしょうか。前述のように、バックエンド コードはフィルタリングを実行せず、ユーザー入力名パラメータをデータベース クエリ ステートメントに直接連結します。そのため、悪意のあるペイロード「test ' or 1=1#」を入力すると、バックエンド コードは次のクエリを生成します。

$クエリ = "ユーザー名が「test」または 1=1# であるメンバーの ID、メールを選択"

このステートメントがデータベースで実行されると、結果は明らかです。データベースは式 1=1 を常に true として評価し、メンバー テーブル内のすべてのデータを返します。

SQLインジェクション_03

SQLインジェクションを防ぐ方法

SQL インジェクションを防ぐには、開発者は Web アプリケーションがユーザー入力を適切にサニタイズするようにする必要があります。これには通常、SQL コマンドをデータ入力から分離する準備済みステートメントとパラメーター化されたクエリの採用が含まれ、それによって悪意を持って挿入された SQL コードの実行が防止されます。定期的なコード レビューとセキュリティ テストは、SQL インジェクションによって悪用される可能性のある脆弱性を特定して修正するのにも役立ちます。

さらに、堅牢な ウェブアプリケーションファイアウォール (WAF) SQL インジェクション攻撃に対する追加の防御層を提供できます。 CDネットワークWAF 悪意のあるリクエストがデータベース サーバーに到達する前に検出してブロックするのに役立ちます。開発者に安全なコーディング プラクティスを教育し、入力検証の重要性についての認識を高めることも、SQL インジェクション攻撃を防ぐ上で重要です。