10

ユーザーがファイルをアップロードすると、ランダムに別のユーザーのアップロードに置き換えられます.PHPとtmpファイル名が再利用される問題を最終的に追跡しました. これを修正する方法はありますか?より良いランダムな名前を作成する方法はありますか? ランダムなファイル名のシードが弱くなるので、時間の経過とともに劣化するようです? これは、PHP 5.2.8 および FreeBSD 7.0 にあります。

これは、同じ tmp ファイル名がどのように使用され、別のアップロードによって上書きされるかを示すログです: http://pastebin.com/m65790440

どんな助けでも大歓迎です。私はこれを4か月以上修正しようとしてきましたが、時間の経過とともに悪化しています. ありがとうございました。

編集: これは PHP コードの問題ではないことに注意してください。これは PHP コードに到達する前に発生しています。アップロード処理スクリプトに到達する前に、他人のアップロードで上書きされていることを確認する

4

5 に答える 5

5

関連するコードを FreeBSD 7 の libc 実装で_gettemptmp_nameまで追跡した後、ファイルの内容がどのように無効になるかについては不明です。(それを追跡するには、PHP 5.2.8 のコピーをダウンロードして、 227 行目から始まる関数であるmain/rfc1867.c1018 行目の呼び出しを読むことができますmain/php_open_temporary_file.c。これは、97 行目から始まる関数の主な作業ですが、基本的にはシステム上の mkstemp の単なるラッパーであり、FreeBSD の libc 実装の 66 行目 (リンク) にあり、_gettemp (上記と同じ) を使用実際にランダムなファイル名を生成します。関数は再入可能ではありません。arc4random()2 つの同時リクエストが重要なコード セクションに入り、同じものを返す可能性がありますtmp_name。Apache が mod_php または php-cgi でどのように機能するかについてはほとんど知りません。現時点ではこれについてうまくコメントできません)。

ただし、ファイルtmp_name自体が無効であるのではなく、代わりに他のアップロードされたファイルと競合する場合 (たとえば、保存されたファイル名の一意性の唯一のソースとして tmp_name のファイル名部分を使用する場合)は、最も簡単な解決策を目指してください。誕生日のパラドックスが原因で衝突に直面している可能性があります。別の質問では、約 5,000,000 個のファイルを移動する必要があると述べており、さらに別の質問では、1 日に 30 ~ 40,000 のアップロードを受信して​​いると述べています。これは、誕生日のパラドックス衝突の主要な状況だと思います。mktempのマニュアルページ(PHPのように6つの「X」を使用する場合)56,800,235,584の可能なファイル名(62 ** 6、または62 ** nで、n =「X」の数など)があると述べています。ただし、約 500 万を超えるファイルがある場合、衝突の確率は約 100%です (((files*(files-1)) /2)/(62**6) は、ファイル = 5,000,000) を意味します。これが直面している問題である場合 (おそらく、生成されたアップロード ファイル名にさらにエントロピーを追加しない場合move_uploaded_file($file['tmp_name'], UPLOADS.sha1(mt_rand().$file['tmp_name']).strrchr($file['name'], '.')))、次のようなことを試すことができます。つまり、ランダムなファイル名にランダム性を追加して、衝突を防ぐというアイデアです。別の方法として、 の 134 行目にさらに 2 つの「X」を追加しmain/php_open_temporary_file.cて再コンパイルすることもできます。

于 2010-07-19T16:52:57.477 に答える
4

PHP のインストール、または PHP がランダムなファイル名 (おそらくtempnam ) を生成するために内部で使用しているシステム コールのいずれかに重大な問題があるようです。

それ以外の方へ: PHP は、ユーザー コードが処理される前に、アップロードされたファイルを内部的に処理します。これらの名前は$_FILES['file']['tmp_name']('file' はフォーム上のファイル入力要素の (引用された) 名前です) に保存されます。

于 2009-03-10T19:32:24.237 に答える
2

PHP は Apache の下で実行されていmod_phpますか?

名前に phpを含むプロセスごとの一時アップロード ディレクトリを作成してから、そのディレクトリにPHP プロセスを作成してみてください。リクエストごとに新しいプロセスが生成される場合、これは機能しません。getmypid()ini_setupload_tmp_dirphp

于 2009-03-10T19:28:10.630 に答える
0

ファイルがアップロードされたら、ファイルをユーザー ディレクトリに移動します。これらの一時ファイルは削除する必要があります。

于 2009-03-10T19:28:58.257 に答える
-1

ファイル名に GUID ジェネレーターを使用することをお勧めします。

于 2009-03-10T19:25:57.233 に答える