現在の位置: ホーム> 最新記事一覧> PHP RealPathを使用してファイルの実際のパスを取得し、ソフトリンクの問題を避ける方法は?

PHP RealPathを使用してファイルの実際のパスを取得し、ソフトリンクの問題を避ける方法は?

gitbox 2025-05-29

1。realpath()関数の紹介

PHPのRealPath()関数は指定されたパスの絶対パスを返し、シンボリックリンク、相対パス(など)などを解析するために使用されます。

 $realPath = realpath('/var/www/html/../index.php');
echo $realPath;

このコードは、 /var/www/ index.phpの絶対パスを出力します。

2。ソフトリンクによって引き起こされる問題

ソフトリンクは、別のファイルまたはディレクトリへの参照です。 Linuxシステム、特に展開環境(nginxルートを使用してソフトリンクディレクトリを指すなど)で非常に一般的です。問題は次のとおりです。

  • RealPath()は、ソフトリンクによって指された実際のパスを解析して返します。

  • 許可制御またはパスマッチングのためにパスに依存している場合、 RealPath()によって返されるパスはあなたの期待と矛盾する可能性があります。

  • いくつかのシナリオ(ホワイトリストの検証など)では、ソフトリンクの解像度後のパスが制限をバイパスする可能性があります。

次のファイル構造があるとします。

 /data/app/storage/real/
/data/app/storage/link -> /data/app/storage/real/

コードは次のとおりです。

 $path = '/data/app/storage/link/file.txt';
echo realpath($path);

出力は次のとおりです。

 /data/app/storage/real/file.txt

現時点では、リターンパスにリンクが含まれると予想される場合、 RealPath()の動作は目標と一致しません。

3.ソフトリンクによって引き起こされる問題を回避する方法

1。realpath()を避けます

絶対的なパスを取得したい場合、ソフトリンクを解析するかどうかを気にしない場合は、次のメソッドの組み合わせを使用して取得できます。

 $absolutePath = rtrim(getcwd(), '/') . '/' . ltrim($relativePath, '/');

これはソフトリンクを解決せず、通過するパスの元の構造を保持します。

2。ReadLink ()を使用して、ソフトリンクかどうかを判断します

パスがソフトリンクであるかどうかを判断し、自分でロジックを処理できます。

 if (is_link($path)) {
    $target = readlink($path);
    echo "これはソフトリンクです,目標はです:" . $target;
}

プロジェクトの要件に基づいてリンクをたどるか、元のパスを保持するかどうかを決定できます。

3.パスを手動で正規化する(ソフトリンクの解像度なし)

以下は、RealPath()に依存しないパス正規化関数です。

 function normalizePath($path) {
    $parts = [];
    foreach (explode('/', $path) as $segment) {
        if ($segment === '' || $segment === '.') {
            continue;
        }
        if ($segment === '..') {
            array_pop($parts);
        } else {
            $parts[] = $segment;
        }
    }
    return '/' . implode('/', $parts);
}

$input = '/data/app/storage/link/../link/file.txt';
echo normalizePath($input);

これはをきれいにしますそして..パスでは、ソフトリンクを解決しません。

4.元のパスとRealPathパスを比較します

許可制御中に、元のパスとRealPath()パスを同時に記録して、許可を比較することができます。

 $originalPath = '/data/app/storage/link/file.txt';
$realPath = realpath($originalPath);

if (strpos($realPath, '/data/app/storage/real/') !== 0) {
    die('このパスは許可されていません');
}

このアプローチは、ソフトリンクが敏感なパスを指す問題に対処するのに適しています。

4。実用的なアプリケーションの提案

  • ディレクトリ確認のアップロードRealPath()を使用する前に元のパスが合法かどうかを確認し、解像度後にパスが許容範囲内にあることを確認してください。

  • 開発環境のデバッグ:展開環境で使用される多くのソフトリンクがあります。一貫性のないパスによって引き起こされるバグを避けるために、デバッグ中にパスの変更に注意を払ってください。

  • フレームワーク開発:フレームワークを開発している場合は、 RealPath()に直接依存する代わりに、カスタムパス解像度ツールを提供することをお勧めします。

5。概要

PHPのRealPath()は、ソフトリンクを処理するときに実際にパスの均一性とシンプルさをもたらす可能性がありますが、解析の動作によりパスの切断を引き起こす可能性もあります。高いセキュリティと一貫性の要件を持つアプリケーションの場合、実際のニーズに基づいてより微細なパス処理戦略を採用し、必要に応じてRealPath()のみに依存しないようにパス分析ロジックを自分で実装することをお勧めします。