SQL インジェクション

Beginner

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、攻撃者がデータベースとやり取りするWebアプリケーションの脆弱性を悪用するために使用する手法であるSQLインジェクションについて学びます。SQLインジェクション攻撃により、不正な手段で機密データにアクセスしたり、データを操作したり、さらにはシステム全体を乗っ取ったりすることが可能になります。

この実験の目的は、脆弱なWebアプリケーションの脆弱性を悪用することで、SQLインジェクションの実践的な経験を積むことです。潜在的なSQLインジェクションの脆弱性を特定する方法、悪意のあるSQLクエリを作成する方法、およびデータベースから機密情報を抽出する方法を学びます。さらに、SQLインジェクション攻撃を軽減するための防御メカニズムとベストプラクティスについても学びます。


Skills Graph

実験環境のセットアップ

このステップでは、脆弱なWebアプリケーションとデータベースサーバーを含む実験環境をセットアップします。

  1. ターミナルを開き、/home/labex/project ディレクトリに移動します。

    cd /home/labex/project
  2. project ディレクトリには2つのPythonファイルがあります。app.pysetup_db.py です。app.py ファイルには脆弱なWebアプリケーションのソースコードが含まれており、setup_db.py ファイルにはデータベースをセットアップするコードが含まれています。

  3. setup_db.py スクリプトを実行して、データベースを作成し、サンプルデータを入力します。

    python3 setup_db.py
  4. Webアプリケーションサーバーを起動します。

    python3 app.py

サーバーが http://localhost:5000 で実行されていることを示すメッセージが表示されるはずです。

SQLインジェクションの脆弱性を特定する

このステップでは、Webアプリケーションにおける潜在的なSQLインジェクションの脆弱性を特定する方法を学びます。

  1. Webブラウザを開き、http://localhost:5000 にアクセスします。
    Webアプリケーションのホームページ
  2. ユーザーデータがサーバーに送信される入力フィールド(例えば検索ボックス)を探します。
  3. 入力フィールドに特殊文字やSQLキーワード(例:', ", --, ;)を入力し、アプリケーションの動作を観察します。
  4. アプリケーションがエラーメッセージを表示したり、予期しない動作をする場合、潜在的なSQLインジェクションの脆弱性がある可能性があります。
    検索ボックスの入力テスト
    検索ボックスにシングルクォート (') を入力して「検索」ボタンをクリックすると、アプリケーションはエラーメッセージなしに No results found を表示します。この動作は、アプリケーションがSQLインジェクションに対して脆弱である可能性を示唆しています。

SQLインジェクションの脆弱性を悪用する

このステップでは、特定したSQLインジェクションの脆弱性を悪用して、データベースから機密情報を抽出する方法を学びます。

  1. 前のステップで特定した脆弱な入力フィールドまたはパラメータを見つけます。

  2. 入力フィールドまたはパラメータに異なるSQLインジェクションペイロードを挿入してみます。

  3. SQLインジェクションペイロードを使用して、データベースから機密情報を抽出してみます。例えば、次のペイロードを使用してデータベースからデータを抽出できます。

    ' UNION SELECT username, password FROM users --

    上記のペイロードは、データベースの users テーブルからユーザー名とパスワードを取得するために使用できます。

  4. アプリケーションの応答を観察し、表示される機密情報や、データベースの構造または内容に関する情報を明らかにする可能性のあるエラーを探します。

SQLインジェクションの脆弱性を軽減する

このステップでは、SQLインジェクションの脆弱性を軽減するための防御メカニズムとベストプラクティスについて学びます。

  1. 脆弱なWebアプリケーションのソースコードをレビューし、ユーザー入力が適切なサニタイズなしにデータベースクエリで使用されている部分を特定します。

  2. 入力検証とサニタイズの手法を実装します。例えば以下のようなものです。

    • パラメータ化クエリまたはプリペアドステートメント
    • 入力検証とサニタイズ(例:特殊文字の削除またはエスケープ)
    • データベースアカウントの最小権限の原則
  3. ユーザー入力を含むデータベースクエリを実行する際に、アプリケーションのコードを更新してパラメータ化クエリまたはプリペアドステートメントを使用するようにします。
    app.py ファイルを以下のように変更します。

    sql_query = "SELECT username, password FROM users WHERE username LIKE '%{}%' OR '{}'".format(query, query)
    cur.execute(sql_query)

    sql_query = "SELECT username, password FROM users WHERE username LIKE?"
    cur.execute(sql_query, ('%' + query + '%',))

    に変更します。そして、results = cur.fetchall()logging.info(f"Search query: {query}") の行の下に移動します。

    logging.info(f"Search query: {query}")
    
    results = cur.fetchall()
  4. 上記の変更を行った後、ファイルを保存し、Webアプリケーションサーバーを再起動します。

    ctrl+c を使用してサーバーを停止し、次のコマンドで再度起動します。

    python3 app.py
  5. 更新されたアプリケーションをテストして、SQLインジェクション攻撃がもはや不可能であることを確認します。

まとめ

この実験では、攻撃者がデータベースとやり取りするWebアプリケーションの脆弱性を悪用するために使用する手法であるSQLインジェクションについて学びました。脆弱なWebアプリケーションとデータベースサーバーをセットアップし、潜在的なSQLインジェクションの脆弱性を特定し、それらを悪用してデータベースから機密情報を抽出しました。さらに、入力検証、サニタイズ、パラメータ化クエリまたはプリペアドステートメントの使用など、SQLインジェクション攻撃を軽減するための防御メカニズムとベストプラクティスについて学びました。

この実践的な経験を通じて、SQLインジェクション攻撃とWebアプリケーションにおけるその防止方法についてより深い理解を得ました。また、安全なコーディング慣行の重要性と、データベースとのやり取り時にユーザー入力を適切にサニタイズしないことの潜在的な結果についても学びました。