関連するコードを FreeBSD 7 の libc 実装で_gettemptmp_name
まで追跡した後、ファイルの内容がどのように無効になるかについては不明です。(それを追跡するには、PHP 5.2.8 のコピーをダウンロードして、 227 行目から始まる関数であるmain/rfc1867.c
1018 行目の呼び出しを読むことができます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
て再コンパイルすることもできます。