web-dev-qa-db-ja.com

PHP |ユーザーのアップロードを許可するためのセキュリティ

私の状況:

[〜#〜] php [〜#〜]を使用して、ユーザーがファイルのウイルスをスキャンできるようにするWebアプリケーションを作成しています。これにより、ユーザーはhtml "file"入力タイプまたはURLを介してファイルをアップロードできます。私はhtmlとPHPサイドをうまく構築し、ユーザーはサーバーにファイルを正常にアップロードできます。Windowsサーバー2012 R2をIIS私のサーバーとして。

私の質問:

私の知る限り、Webサイトのセキュリティ/攻撃の脆弱性を回避するためのセキュリティ(スクリプトとサーバー側の両方)はほとんどまたはまったくありません。攻撃者が私のサーバーをハッキングする可能性のあるファイルをアップロードして実行する可能性があることを知っています。 つまり、これらの問題を解決するためにどのような手順を実行できますか

私が認識しているもの:

私が行った研究のおかげで、自分を強化するために次のことを実行できる可能性があると理解していますが、これらはすべて理論であり、実際にそれらを適切に配置する方法がわかりません(そのため、なぜ私が尋ねているのでしょうか)。

  • ファイルタイプの制限(はい、.phpファイルをブロックする可能性がありますが、例として-ユーザーが実行可能ファイルをスキャンする可能性が高いため、一般的な.exeをブロックできません)この種類のサービスは、ファイルタイプを制限しすぎると使いやすさが失われるだけです

  • アップロードしたファイルを別のドライブに保存する-サイトディレクトリはCドライブにあり、使用できる空のDドライブがあります。 サーバーが特定のドライブで何かを実行できないようにするにはどうすればよいですか?ハッカーがそのドライブに移動してアップロードされたファイルを実行しないようにするにはどうすればよいですか?

私が試したもの:

  • アップロードしたファイルのmd5ハッシュに名前を変更する関数を作成しました。先頭に一意のIDを付けているため、ユーザーがファイルを簡単に識別できません。
  • .phpアップロードを削除するためのファイルタイプが制限されていますか?おそらく、私の目的に有効な他のものはありますか?

結論:

したがって、基本的に、上記のマイナーな質問への回答と同様です。可能性のある脅威を排除するために、アプリケーションとサーバーを強化するために実行できるアクションのリストを探しています。ありがとう

コード:

補足として、以下に私のコードを示します。あなたがそこに深刻な何かを見つけた場合に備えて。または、コードに追加できる追加のセキュリティがあります。

PHP:

$upload_directory = "uploads/";
    $uploaded_file = $upload_directory . basename($_FILES["file"]["name"]);
    $upload_ok = 1;

    $image_file_type = pathinfo($uploaded_file, PATHINFO_EXTENSION);

    // check for files bigger then 8mb
    if($_FILES["file"]["size"] > 8388608){
        print "your file exceeds 8mb";
        $upload_ok = 0;
        exit();
    }

    // only allow certain file types
    if($image_file_type != "jpg" && $image_file_type != "png" && $image_file_type != "jpeg" && $image_file_type != "gif"){
        print "invalid file type";
        $upload_ok = 0;
        exit();
    }

    // upload it
    if($upload_ok != 0){
        move_uploaded_file($_FILES["file"]["tmp_name"], $uploaded_file);
    }

HTML:

<form method="post" action="index.php" enctype="multipart/form-data">

    <label>Select Desired File</label><br>
    <input type="file" name="file" id="file">

    <input type="submit" name="submit" value="Scan File"> 
</form> 
7
Jimmy

ユーザーファイルのアップロードを許可する場合は、十分に注意する必要があります。これは、頭から離れて、始めるための単なるリストです。

ユーザーがファイルを実行できないようにする

  • PHPファイルが存在するフォルダでPHPファイル拡張子の使用を考慮しないようにPHPを設定します。
  • ファイルの権限が正しく設定されていることを確認してください。 uploadedファイルに実行権限を付与する必要がない場合、なぜそれらを実行する必要がありますか?

ユーザーが任意のファイルを取得できないようにする

本当に必要な場合を除き、サービスにアップロードされたすべてのファイルをユーザーが列挙できないようにする必要があります。実際、あなたのサービスの説明に基づいて、彼らが再びファイルをダウンロードできるはずである理由はありません。

  • ファイル名に一意のIDを推測するのは難しいものを提供します。多くのサイトでは、メタデータを提供し、列挙を防ぐために、画像のように簡単なものに長く複雑なファイル名を使用しています。
  • システムが列挙を検出するように設定されていることを確認してください。ユーザーは、リソースの名前で何千もの誤った推測を行うことができないようにする必要があります。これは、i.pテーブル、fail2ban、IDS、アプリケーション、データベースを通じて実行できます。たくさんのことと行く方法の多くに依存します。
  • ユーザーがサーバーから上記のファイルを取得する必要がない場合は、ファイルに直接アクセスできない場所(webrootの外部など)に移動してください。
  • 他のアプリケーションパーツ(ビジネスロジックなど)とは異なるサーバーでファイルをホストすることを検討してください。

ファイルがシステムに直接問題を引き起こさないようにする

サービスをウイルススキャンサービスとして説明します。あなたがしようとしていることは危険かもしれません。ウイルスがAV自体を利用して特権を昇格させることは考えられます。

  • AVに送信する前に、基本的なスキャンを行ってファイルの有効性を確認します。ユーザーは、AVをクラッシュさせる可能性のある深刻な破損ファイルを送信できないようにする必要があります。
  • ヘッダーを確認してください。
  • Fileinfoなどのプログラムを使用します。
  • 既知のファイルタイプ情報と照合してください。
  • 明白なマングリング/ファジングの試みがないかファイルをスキャンします。たとえば、10,000文字のAで埋められたファイルがシステムをテストしている可能性があります。

AVが問題を引き起こさないことの確認

  • 完全にパッチされ、最新の信頼できるAVソフトウェアを使用していることを確認してください。
  • AVソフトウェアに適切な権限があり、不要なポートが公開されていないことを確認してください。

違反の場合にシステムを隔離する

  • 繰り返しますが、ファイルを保持しているシステムが最小限の権限を持っていることを確認してください。
  • ある種のコンテナー/刑務所/サンドボックスを使用して、エクスプロイトの試みの効果を制限してください。
4
baordog

ファイルがアップロードされたら、ファイル拡張子に関係なく finfo を使用してファイルのタイプを判別し、結果に応じて特定のアクションを実行することをお勧めします。

アップロードフォルダがドキュメントルートのどこかにあると判断した場合は、その特定のフォルダの 無効化された実行 of PHPファイル)にすることをお勧めします。

より強力なハッシュアルゴリズムを使用して、ファイルごとにランダムな文字列と組み合わせてファイルの名前を変更します。ファイルの名前を変更する方法を説明する方法はかなり予測可能であるように思われ、攻撃者として私はファイル名を推測するためにこのようなことを試みます。

3
Jeroen