まず、ファイルをアップロードするということは、ユーザーがさまざまな形式で大量のデータを提供していること、およびユーザーがそのデータを完全に制御できることを意味します。これは、通常の形式のテキスト フィールドの場合でも問題です。ファイルのアップロードは同じですが、それ以上です。最初のルールは次のとおりです。それを信用しないでください。
ファイルのアップロードでユーザーから得られるもの:
これらはファイル アップロードの 3 つの主要なコンポーネントであり、どれも信頼できません。
の MIME タイプを信頼しないでください$_FILES['file']['type']
。これは完全に任意のユーザー提供の値です。
重要なことにはファイル名を使用しないでください。これは完全に任意のユーザー提供の値です。一般に、ファイル拡張子や名前を信頼することはできません。などを使用してファイルをサーバーのハードディスクに保存しないでください'dir/' . $_FILES['file']['name']
。名前が の場合、'../../../passwd'
他のディレクトリのファイルを上書きしています。ファイルを保存するには、常にランダムな名前を自分で生成してください。必要に応じて、元のファイル名をメタデータとしてデータベースに保存できます。
誰にも、何かに勝手にファイルにアクセスさせてはいけません。たとえば、攻撃者がmalicious.php
ファイルをサーバーにアップロードし、それをサイトの webroot ディレクトリに保存している場合、ユーザーは単にアクセスしexample.com/uploads/malicious.php
てそのファイルを実行し、サーバー上で任意の PHP コードを実行できます。
任意のアップロードされたファイルを公の場所に保存しないでください。常に、アプリケーションだけがアクセスできる場所に保存してください。
特定のプロセスにのみファイルへのアクセスを許可します。画像ファイルであることが想定されている場合は、画像を読み取ってサイズを変更するスクリプトのみがファイルに直接アクセスできるようにします。このスクリプトでファイルの読み取りに問題がある場合は、おそらく画像ファイルではないため、フラグを立てるか破棄してください。他のファイルの種類についても同様です。ファイルを他のユーザーがダウンロードできるようにする場合は、ダウンロード用にファイルを提供し、それ以外には何もしないスクリプトを作成します。
扱っているファイルの種類がわからない場合は、ファイルの MIME タイプを自分で検出するか、特定のプロセスでファイルを開くようにしてください (たとえば、画像のサイズ変更プロセスで想定される画像のサイズを変更しようとします)。ここでも注意してください。そのプロセスに脆弱性がある場合、悪意を持って作成されたファイルがそれを悪用し、セキュリティ侵害につながる可能性があります (このような攻撃の最も一般的な例は、Adobe の PDF リーダーです)。
特定の質問に対処するには:
[T]これらの画像のサイズもチェックするには、/tmp フォルダーに保存する必要があります。危険じゃないですか?
いいえ。一時フォルダー内のファイルにデータを保存するだけでは、そのデータで何もしていない場合は危険ではありません。データは、その内容に関係なく、単なるデータです。データを実行しようとしている場合、またはプログラムがデータを解析している場合にのみ危険です。プログラムに解析の欠陥が含まれていると、悪意のあるデータによってだまされて予期しないことを実行する可能性があります。
もちろん、何らかの悪意のあるデータがディスク上に存在することは、悪意のあるデータがどこにも存在しない場合よりもリスクが高くなります。誰がやって来て何かをするかは決してわかりません。そのため、アップロードされたデータを検証し、検証に合格しない場合はできるだけ早く破棄する必要があります。
いたずら者が URL を教えてくれて、マルウェアだらけの Web サイト全体をダウンロードしてしまったらどうしますか?
何をダウンロードするかはあなた次第です。1 つの URL から得られるデータのブロブは最大でも 1 つです。そのデータを解析していて、最初の blob に基づいてさらに多くの URL のコンテンツをダウンロードしている場合、それが問題です。やらないでください。しかし、仮にそうしたとしても、一時ディレクトリがいっぱいになってしまいます。繰り返しますが、そのようなもので危険なことをしていなければ、これは危険ではありません。