私のクライアントは、ユーザーが写真コンテストに応じて写真をアップロードできる写真サイトを望んでいます。技術的にはこれは問題ではありませんが、ユーザーがサーバーに画像をアップロードできるようにすることに関連するリスクを知りたいです。リスクが高いと感じている...
私はこのようなものを使うことを考えていました http://www.w3schools.com/php/php_file_upload.asp
匿名ユーザーにファイルのアップロードを許可する場合、画像(および潜在的に悪意のあるファイル)がアップロードされるディレクトリをどのように保護できますか?
最大の懸念は、悪意のあるユーザーが画像以外のものをサーバーにアップロードすることです。具体的には、サーバーをだまして実行しようとする実行可能ファイルまたはスクリプトをアップロードする可能性があります。
これを防ぐ1つの方法は、PHPで_move_uploaded_file
_を実行した後、ファイルが実行可能にならないようにすることです。これは chmod()
を使用して644の権限を設定するのと同じくらい簡単です。
ユーザーは引き続きPHPスクリプトまたは他のスクリプトをアップロードし、構成に応じてApacheをだましてそれらを実行させることができます。
これを回避するには、アップロード後にファイルに対して getimagesize()
を呼び出し、ファイルの種類を判別します。 ファイル名を一意のファイル名に変更し、独自の拡張子を使用します。これにより、ユーザーが_evil.jpg.php
_をアップロードした場合、スクリプトはそれを_12345.jpg
_として保存し、実行できなくなります。さらに良いことに、スクリプトは無効なJPEGであるため、それに触れることさえありません。
私は個人的に常にアップロードされた画像の名前をtime()
からの現在のタイムスタンプまたはUUIDに変更します。これは、非常に悪質なファイル名(_../../../../../../../../etc/passwd
_という名前のファイルをアップロードしようとする人など)を防ぐのにも役立ちます。
さらなる保護として、「イメージファイアウォール」と呼ばれることもある機能を使用できます。基本的に、これはドキュメントルートのoutsideであるディレクトリにアップロードされた画像を保存し、 readfile()
を呼び出すPHPスクリプトを介して表示することを含みます。 それらを表示します。これは大変な作業かもしれませんが、最も安全なオプションです。
二次的な懸念は、ユーザーがアップロードするファイルが多すぎるか、ファイルが大きすぎるか、利用可能なすべてのディスク容量を消費している、またはホスティングユーザーのクォータがいっぱいであるということです。これは、個々のファイルのサイズの制限、1人のユーザーがアップロードできるデータの量、すべてのアップロードの合計サイズなどを含む、ソフトウェア内で管理できます。Webサイト管理者ユーザーがこれらのファイルを管理および削除する方法を持っていることを確認してください。
_$_FILES
_のデータに依存しない。多くのサイトでは、_$_FILES[0]['type']
_から、またはファイル名の拡張子を確認することにより、ファイルのMIMEタイプを確認するように指示しています。 これを行わないでください。 _$_FILES
_を除き、_tmp_name
_の下にあるものはすべて、悪意のあるユーザーによって操作される可能性があります。 画像が必要なことがわかっている場合は、実際に画像データを読み取り、ファイルが実際に画像であるかどうかがわかるため、getimagesize
のみを呼び出します。
セキュリティのHTTPリファラーのチェックに依存しないでください。多くのサイトでは、ファイルが正当であることを確認するために、参照元が自分のサイトであることを確認することをお勧めします。これは簡単に偽造できます。
詳細については、ここにいくつかの良い記事があります:
重要なヒントについては https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet#File_uploads を参照してください。
getimagesize()をだまして、PHPコードを実行することができます。
http://www.php.net/manual/en/features.file-upload.php は、finfo(FILEINFO_MIME_TYPE)でより良い代替手段を提供するCertaiNによるユーザーコメントがあります