ファイルをアップロードする最も安全な方法は何ですか?
-
05-07-2019 - |
質問
私が勤務している会社は、最近、ホストするサイトで多くのヘッダーインジェクションとファイルアップロードエクスプロイトに見舞われており、ヘッダーインジェクション攻撃に関する問題を修正していますが、アップロードエクスプロイトをまだ制御できていません。
プラグアンドプレイタイプの一連のアップロードスクリプトをセットアップして、デザイナーがサイトの構造にコピーし、いくつかの変数を変更し、すぐに使用できる社内で使用するようにしています。サイトにフォームをアップロードします。できるだけ露出を制限したいと考えています(fopenとシェルコマンドは既にシャットダウンしています)。
過去1時間、サイトを検索しましたが、外部ソースに依存する特定の方法を扱う多くの異なる答えを見つけました。信頼性の高い保護方法として使用するのに十分具体的な、スクリプトのみの最適なソリューションは何だと思いますか?また、可能であれば、言語をPHPまたは擬似コードに制限したいです。
編集:答え(下記に投稿)を見つけましたが、シェルコマンドexec()を使用している間、スクリプトファイルのアップロードをブロックすると(このソリューションはそうします)非常によく)、あなたは問題に遭遇しません。
解決
最善の解決策、IMHOは、アップロードされたファイルを含むディレクトリを" web"の外側に置くことです。環境を作成し、スクリプトを使用してダウンロード可能にします。このようにして、誰かがスクリプトをアップロードしたとしても、ブラウザからスクリプトを呼び出して実行することはできず、アップロードされたファイルのタイプを確認する必要はありません。
他のヒント
-
許可されたユーザーのみにファイルのアップロードを許可します。プリミティブボットを妨げるためにキャプチャを追加することもできます。
-
まず、アップロードフォームで
MAX_FILE_SIZE
を設定し、最大ファイルsize
と<サーバー上のcode> count も。ini_set('post_max_size', '40M'); //or bigger by multiple files ini_set('upload_max_filesize', '40M'); ini_set('max_file_uploads', 10);
アップロードされたファイルでサイズチェックを行う:
if ($fileInput['size'] > $sizeLimit) ; //handle size error here
-
$ _ FILES
とmove_uploaded_file()
を使用して、アップロードしたファイルを正しいディレクトリに配置するか、処理する場合はis_uploaded_file( )
。 (これらの関数は、register_globals
によるファイル名の挿入を防ぐために存在します。)$uploadStoragePath = '/file_storage'; $fileInput =
も。-
許可されたユーザーのみにファイルのアップロードを許可します。プリミティブボットを妨げるためにキャプチャを追加することもできます。
-
まず、アップロードフォームで
MAX_FILE_SIZE
を設定し、最大ファイルsize
と<サーバー上のcode> count
ini_set('post_max_size', '40M'); //or bigger by multiple files ini_set('upload_max_filesize', '40M'); ini_set('max_file_uploads', 10);
アップロードされたファイルでサイズチェックを行う:
if ($fileInput['size'] > $sizeLimit) ; //handle size error here
-
-
$ _ FILES
とmove_uploaded_file()
を使用して、アップロードしたファイルを正しいディレクトリに配置するか、処理する場合はis_uploaded_file( )
。 (これらの関数は、register_globals
によるファイル名の挿入を防ぐために存在します。)SetHandler none SetHandler default-handler Options -ExecCGI php_flag engine off
常に元のファイル名を使用する代わりにランダムIDを生成します。
-
新しいサブドメイン を作成します(例: http://static.example.com または少なくとも
public_html
以外の新しいディレクトリ、アップロードされたファイル用。このサブドメインまたはディレクトリはファイルを実行しない。サーバー構成で設定するか、 < strong>.htaccess
ファイル ディレクトリごと。$noExecMode = 0644; chmod($uploadedFile, $noExecMode);
設定
chmod()
も同様です。$userContent = '../uploads/malicious.jpg'; include('includes/'.$userContent);
新しくアップロードされたファイルにも
chmod()
を使用して、ディレクトリに設定します。 -
ハッカーによって送信された MIMEタイプ を確認する必要があります。許可される mimeタイプのホワイトリストを作成する必要があります。他の形式が不要な場合は、画像のみを許可します。その他の形式はセキュリティ上の脅威です。画像もありますが、少なくともそれらを処理するツールがあります...
たとえば、破損したコンテンツ:画像ファイルの HTML は、XSS を引き起こす可能性があります/ questions / 18337630 / what-is-x-content-type-options-nosniff "> コンテンツスニッフィングの脆弱性。破損したコンテンツが PHP コードの場合、 evalインジェクション脆弱性と組み合わせることができます。 Strict-Transport-Security: max-age={your-max-age} X-Content-Type-Options: nosniff X-Frame-Options: deny X-XSS-Protection: 1; mode=block Content-Security-Policy: {your-security-policy}
これを回避するために、たとえば、phpファイルを手動で含める代わりに
class autoloader
を使用してください...
最初に javascriptインジェクションを処理するには、ブラウザで xss およびコンテンツスニッフィングをオフにする必要があります。 コンテンツスニッフィングの問題は、古い msie でよく見られますが、他のブラウザではかなりうまくフィルタリングされていると思います。とにかく、あなたはこれらの問題をたくさんのヘッダーで防ぐことができます。 (すべてのブラウザで完全にサポートされているわけではありませんが、クライアント側でできる最善の方法です。)try { $uploadedImage = new Imagick($uploadedFile); $attributes = $uploadedImage->identifyImage(); $format = $image->getImageFormat(); var_dump($attributes, $format); } catch (ImagickException $exception) { //handle damaged or corrupted images }
Imagick識別でファイルが破損しているかどうかを確認できます
、しかしそれは完全な保護を意味するものではありません。X-Download-Options: noopen Content-Disposition: attachment; filename=untrustedfile.html
他の MIMEタイプを提供する場合は、常に強制ダウンロード する必要があります。含めないあなたが何をしているか本当に理解していない限り、それらをウェブページに...
<*> -
たとえば exif データなどのコードを含む有効な画像ファイルを作成できます。そのため、コンテンツが重要でない場合は、画像から exif をパージする必要があります。
Imagick
またはGD
でそれを行うことができますが、どちらもファイルの再パックが必要です。アルとしてexiftool
を見つけることができますFILES['image']; if ($fileInput['error'] != UPLOAD_ERR_OK) ; //handle upload error here, see http://php.net/manual/en/features.file-upload.errors.php //size check here $temporaryName = $fileInput['tmp_name']; $extension = pathinfo($fileInput['name'], PATHINFO_EXTENSION); //mime check, chmod, etc. here $name = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); //true random id move_uploaded_file($temporaryName, $uploadStoragePath.'/'.$name.'.'.$extension);常に元のファイル名を使用する代わりにランダムIDを生成します。
-
新しいサブドメイン を作成します(例: http://static.example.com または少なくとも
<*>public_html
以外の新しいディレクトリ、アップロードされたファイル用。このサブドメインまたはディレクトリはファイルを実行しない。サーバー構成で設定するか、 < strong>.htaccess
ファイル ディレクトリごと。設定
<*>chmod()
も同様です。新しくアップロードされたファイルにも
chmod()
を使用して、ディレクトリに設定します。 -
ハッカーによって送信された MIMEタイプ を確認する必要があります。許可される mimeタイプのホワイトリストを作成する必要があります。他の形式が不要な場合は、画像のみを許可します。その他の形式はセキュリティ上の脅威です。画像もありますが、少なくともそれらを処理するツールがあります...
<*>
たとえば、破損したコンテンツ:画像ファイルの HTML は、XSS を引き起こす可能性があります/ questions / 18337630 / what-is-x-content-type-options-nosniff "> コンテンツスニッフィングの脆弱性。破損したコンテンツが PHP コードの場合、 evalインジェクション脆弱性と組み合わせることができます。 これを回避するために、たとえば、phpファイルを手動で含める代わりに
<*>class autoloader
を使用してください...
最初に javascriptインジェクションを処理するには、ブラウザで xss およびコンテンツスニッフィングをオフにする必要があります。 コンテンツスニッフィングの問題は、古い msie でよく見られますが、他のブラウザではかなりうまくフィルタリングされていると思います。とにかく、あなたはこれらの問題をたくさんのヘッダーで防ぐことができます。 (すべてのブラウザで完全にサポートされているわけではありませんが、クライアント側でできる最善の方法です。)Imagick識別でファイルが破損しているかどうかを確認できます
、しかしそれは完全な保護を意味するものではありません。他の MIMEタイプを提供する場合は、常に強制ダウンロード する必要があります。含めないあなたが何をしているか本当に理解していない限り、それらをウェブページに...
<*> -
たとえば exif データなどのコードを含む有効な画像ファイルを作成できます。そのため、コンテンツが重要でない場合は、画像から exif をパージする必要があります。
Imagick
またはGD
でそれを行うことができますが、どちらもファイルの再パックが必要です。アルとしてexiftool
を見つけることができます
Hardened-PHP を使用して構成し、 move_uploaded_file および $ _ FILESスーパーグローバル。最も単純なスクリプトで、最も安全です(少なくとも、実行中のPHPバージョン自体と同じくらい安全です)