はじめに
この実験では、攻撃者がデータベースとやり取りする Web アプリケーションの脆弱性を悪用するために使用する手法である SQL インジェクションについて学びます。SQL インジェクション攻撃により、不正な手段で機密データにアクセスしたり、データを操作したり、さらにはシステム全体を乗っ取ったりすることが可能になります。
この実験の目的は、脆弱な Web アプリケーションの脆弱性を悪用することで、SQL インジェクションの実践的な経験を積むことです。潜在的な SQL インジェクションの脆弱性を特定する方法、悪意のある SQL クエリを作成する方法、およびデータベースから機密情報を抽出する方法を学びます。さらに、SQL インジェクション攻撃を軽減するための防御メカニズムとベストプラクティスについても学びます。
ラボ環境をセットアップする
このステップでは、脆弱な Web アプリケーションとデータベースサーバーを含む実験環境をセットアップします。
ターミナルを開き、
/home/labex/projectディレクトリに移動します。cd /home/labex/projectprojectディレクトリには 2 つの Python ファイルがあります。app.pyとsetup_db.pyです。app.pyファイルには脆弱な Web アプリケーションのソースコードが含まれており、setup_db.pyファイルにはデータベースをセットアップするコードが含まれています。setup_db.pyスクリプトを実行して、データベースを作成し、サンプルデータを入力します。python3 setup_db.pyWeb アプリケーションサーバーを起動します。
python3 app.py
サーバーが http://localhost:5000 で実行されていることを示すメッセージが表示されるはずです。
SQL インジェクションの脆弱性を特定する
このステップでは、Web アプリケーションにおける潜在的な SQL インジェクションの脆弱性を特定する方法を学びます。
- Web ブラウザを開き、
http://localhost:5000にアクセスします。
- ユーザーデータがサーバーに送信される入力フィールド(例えば検索ボックス)を探します。
- 入力フィールドに特殊文字や SQL キーワード(例:
',",--,;)を入力し、アプリケーションの動作を観察します。 - アプリケーションがエラーメッセージを表示したり、予期しない動作をする場合、潜在的な SQL インジェクションの脆弱性がある可能性があります。
検索ボックスにシングルクォート (') を入力して「検索」ボタンをクリックすると、アプリケーションはエラーメッセージなしにNo results foundを表示します。この動作は、アプリケーションが SQL インジェクションに対して脆弱である可能性を示唆しています。
SQL インジェクションの脆弱性を悪用する
このステップでは、特定した SQL インジェクションの脆弱性を悪用して、データベースから機密情報を抽出する方法を学びます。
前のステップで特定した脆弱な入力フィールドまたはパラメータを見つけます。
入力フィールドまたはパラメータに異なる SQL インジェクションペイロードを挿入してみます。
SQL インジェクションペイロードを使用して、データベースから機密情報を抽出してみます。例えば、次のペイロードを使用してデータベースからデータを抽出できます。
' UNION SELECT username, password FROM users --上記のペイロードは、データベースの
usersテーブルからユーザー名とパスワードを取得するために使用できます。アプリケーションの応答を観察し、表示される機密情報や、データベースの構造または内容に関する情報を明らかにする可能性のあるエラーを探します。
SQL インジェクションの脆弱性を軽減する
このステップでは、SQL インジェクションの脆弱性を軽減するための防御メカニズムとベストプラクティスについて学びます。
脆弱な Web アプリケーションのソースコードをレビューし、ユーザー入力が適切なサニタイズなしにデータベースクエリで使用されている部分を特定します。
入力検証とサニタイズの手法を実装します。例えば以下のようなものです。
- パラメータ化クエリまたはプリペアドステートメント
- 入力検証とサニタイズ(例:特殊文字の削除またはエスケープ)
- データベースアカウントの最小権限の原則
ユーザー入力を含むデータベースクエリを実行する際に、アプリケーションのコードを更新してパラメータ化クエリまたはプリペアドステートメントを使用するようにします。
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()上記の変更を行った後、ファイルを保存し、Web アプリケーションサーバーを再起動します。
ctrl+cを使用してサーバーを停止し、次のコマンドで再度起動します。python3 app.py更新されたアプリケーションをテストして、SQL インジェクション攻撃がもはや不可能であることを確認します。
まとめ
この実験では、攻撃者がデータベースとやり取りする Web アプリケーションの脆弱性を悪用するために使用する手法である SQL インジェクションについて学びました。脆弱な Web アプリケーションとデータベースサーバーをセットアップし、潜在的な SQL インジェクションの脆弱性を特定し、それらを悪用してデータベースから機密情報を抽出しました。さらに、入力検証、サニタイズ、パラメータ化クエリまたはプリペアドステートメントの使用など、SQL インジェクション攻撃を軽減するための防御メカニズムとベストプラクティスについて学びました。
この実践的な経験を通じて、SQL インジェクション攻撃と Web アプリケーションにおけるその防止方法についてより深い理解を得ました。また、安全なコーディング慣行の重要性と、データベースとのやり取り時にユーザー入力を適切にサニタイズしないことの潜在的な結果についても学びました。