0

PHPを使用してファイルをアップロードし、データベースも確実に更新されるようにするためのベストプラクティスは何ですか?

現在のアプローチ

1)フォームの検証により、すべてのフィールドが有効なタイプ、長さであり、xss攻撃がないことが確認されます。

2)ユーザーが送信したファイル名でサーバーにアップロードされたファイル

3)ファイル名を含むユーザー提出の詳細で更新されたデータベース

それは安全な方法ですか?最初にデータベースを更新してから、データベースにファイル名を照会してから、データベースで取得したファイル名を使用してファイルをアップロードする方がよいでしょうか。

必ずしもコードを探すのではなく、哲学を探します。ありがとう!

4

2 に答える 2

1

私はこの順序を使用します:

最初の方法:操作順序に依存

  • フォームの検証
  • ファイルがアップロードされたかどうかを確認します(まだ一時ファイルから移動しないでください)
  • 自由な選択に基づいて新しいファイル名を生成します
  • 新しく生成されたファイル名を使用して、ファイルに関するデータをデータベースに挿入します
  • その場合にのみ、例外がスローされない場合は、上記のファイル名を使用してファイルを一時ファイルから移動します。それ以外の場合、ファイルはリクエストの終了時に自動的に削除されます
  • 何らかの理由でファイルの移動に失敗した場合は、データベースからレコードを削除する必要があります。

エラー(関数PDOなど)を発生させるのではなく、例外をスローするため、データベースと「対話」するために、いくつかのようなライブラリを使用することを強くお勧めします。mysql_**そうすれば、データベース関数の結果を常にチェックしなくても、クエリが成功したかどうかを確実に知ることができます...

2番目の方法:トランザクション

  • フォームの検証
  • ファイルがアップロードされたかどうかを確認します(まだ一時ファイルから移動しないでください)
  • 自由な選択に基づいて新しいファイル名を生成します
  • トランザクションを開始します
  • 新しく生成されたファイル名を使用して、ファイルに関するデータをデータベースに「挿入」します。
  • 上記のファイル名を使用して、ファイルを一時ファイルから移動します。何らかの理由でファイルの移動が失敗した場合は、実行をスローします。
  • トランザクションをコミットする
  • この時点で、両方のファイルが移動され、データが適切に保持されていることを確認できます。
于 2012-04-04T20:30:53.607 に答える
1

フォームの検証は、あらゆる Web アプリケーションの重要な部分であるため、リストに記載されていることを確認することをお勧めします。ここでは、Web アプリケーションの最も危険な 2 つの要素、ファイルのアップロードとデータベースのやり取りを組み合わせているため、慎重に処理する必要があります。それがあなたが求めている理由だと思います!

アプローチに関する私の提案は、まず、ユーザーが提出したファイル名を使用しないことです。これにより、必要のないリスク全体が開かれます。これがアプリの必須機能でない限り、PHP で新しいランダム ファイル名を生成し、move_uploaded_file を使用して、PHP によって割り当てられた tmp_name から新しいランダム ファイル名にコピーします。

この移動を実行したら、ファイルの場所でデータベースを更新できます。

したがって、私のアプローチは次のようになります。

  1. ホワイトリスト (提案として [az][AZ][0-9]) に基づいて、ユーザーが入力した入力を厳密に検証します。
  2. ユーザーが提供したデータを画面にエコーバックしないようにします。そうする場合は、出力を HTML エンティティにエンコードします。
  3. データベースまたはファイル名への入力にユーザー提供のデータを使用することは避け、制御できる新しいファイル名を生成します。
  4. アップロード自体を処理し、いくつかの検証チェックを実行した後、生成されたファイル名に従って画像を新しい場所に移動します。
  5. データベースを新しいファイル名で更新します。

あなたがコードを求めていなかったことは知っていますが、ここに私が持っている作業ファイルのアップロードからの小さなスニペットをいくつか示します。データベースの部分は実行しませんが、追加するのは簡単です。

function generate_filename() {
    // could be improved upon really
    $random_string = random_string(8);
    $filename = $random_string . time() . ".jpg";
    return $filename;    
}



if ($_FILES["file_upload"]["size"] != 0) {
    $file_name = generate_filename();
    $file_path = "/" . $upload_directory . "/" . $file_name;
    $target_file_name = SITE_ROOT . $file_path; // SITE_ROOT is a constant for the file system location. This could be /var/www/images for example.

    if ($_FILES["file_upload"]["type"] == "image/jpeg") {
        if (getimagesize($_FILES["file_upload"]["tmp_name"])) {
            if (move_uploaded_file($_FILES["file_upload"]["tmp_name"],$target_file_name)) {
                exit_status("File uploaded successfully to $file_path");
            } else {
                exit_status("Eek, something went wrong with your image upload");
            }
        } else {
            exit_status("Not a valid image");
        }
    } else {
        exit_status("Invalid file type. We only support JPEG");
    }
} else {
    exit_status("You didn’t specify a file to upload. Try again");
}
于 2012-04-04T20:54:08.933 に答える