ファイルインクルージョンの理解
初心者向けに、「ファイルインクルージョン」の概念とその潜在的な脆弱性について詳しく見ていきましょう。
ファイルインクルージョンは、特にコードの再利用性の観点から、プログラミングにおいて一般的な手法です。開発者は頻繁に使用する関数やモジュールを別のファイルにまとめます。これらの関数やモジュールが必要になったとき、開発者は単にそれらのファイルをコードに含めるだけで、同じコードを繰り返し書く必要がなくなります。
PHP には、ファイルインクルージョンに関する 4 つの主要な関数があります。
include()
require()
include_once()
require_once()
以下にそれぞれの概要を簡単に説明します。
include()
: この関数は、呼び出されたときにファイルを含めます。ファイルが見つからない場合、PHP は警告を発しますが、スクリプトは引き続き実行されます。
require()
: この関数は、スクリプトが実行される前にファイルを含めます。ファイルが見つからない場合、PHP は致命的なエラーを発し、スクリプトの実行を停止します。
include_once()
と require_once()
: これらの関数は include()
と require()
と同様に動作しますが、関数が複数回呼び出された場合でも、ファイルが一度だけ含まれることを保証します。
ファイルインクルージョンの方法は大きく 2 つのタイプに分類できます。
- 静的インクルージョン
- 動的インクルージョン
これら 2 つのタイプの違いについては、次のセクションで例を用いて説明します。
このコースでは、/home/labex/project/
ディレクトリにある 3 つの .php
ファイルを探索します。これらは次の通りです。
lfi_static.php
lfi_dynamic.php
echo.php
それぞれのファイルが何をするかを理解しましょう。
-
lfi_static.php
: このファイルは echo.php
ファイルを静的に含めます。つまり、echo.php
ファイルへのパスはハードコードされており、変更されません。この方法は安全で、脆弱性を露出することはありません。
<?php
include("./echo.php");
?>
-
lfi_dynamic.php
: このファイルは、URL の 'file' パラメータに基づいて他のファイルを含めます。このパラメータが提供されない場合、単にその使い方のヒントを表示します。ただし、このパラメータが攻撃者によって制御される場合、この方法は危険な可能性があります。
<?php
if (isset($_GET['file'])) {
include($_GET['file']);
}
else{
echo "You can use the 'file' parameter to include files";
}
?>
-
echo.php
: このファイルは、含められたときに単に成功メッセージを出力します。
<?php
echo 'Great, now you have successfully included the content of echo.php!'
?>
次のコマンドをターミナルで実行して、lfi
テスト用のイメージを準備します。
cd ~/projects
docker build -t lfi-image.
イメージのビルドが完了したら、このイメージを使用して lfi
脆弱性をテストするためのコンテナを起動できます。
docker run -d --name lfi -p 80:80 lfi-image
これで、ブラウザでこれらのファイルをテストできます。たとえば、lfi_static.php
ファイルにアクセスするには、次の URL を入力します。
http://127.0.0.1/LFI/lfi_static.php
lfi_static.php
ファイルが echo.php
の内容を正常に含めていることがわかります。この静的なファイルインクルージョンの方法は安全であることを覚えておいてください。
次に、lfi_dynamic.php
ファイルを見てみましょう。次の URL を使用してこのファイルにアクセスします。
http://127.0.0.1/LFI/lfi_dynamic.php
'file' パラメータを使用するように促すメッセージが表示されます。それでは、これを行い、echo.php
を含めましょう。
http://127.0.0.1/LFI/lfi_dynamic.php?file=./echo.php
echo.php
が正常に含められていることがわかります。これは、ファイルインクルージョンがどのように機能するかを示しています。これは PHP の例ですが、特定の関数は異なる場合がありますが、その原則は他のプログラミング言語にも適用されることを覚えておくことが重要です。