↓ メインコンテンツへスキップ

ファイルアップロードとバリデーション

概要
#

Web フォームから送信されたファイルの安全な受信・保存処理。ファイル名のサニタイズ(secure_filename)、拡張子バリデーション、アップロード容量制限についてのまとめ。

参考ブログ記事
#


1. HTML フォーム側の設定
#

ファイルをアップロードする場合、form タグに enctype="multipart/form-data" を必ず指定する。

1<form method="POST" enctype="multipart/form-data">
2    <input type="file" name="upload_file">
3    <button type="submit">アップロード</button>
4</form>

2. サーバー側の安全な保存処理
#

拡張子チェックとファイル名サニタイズ
#

 1import os
 2from flask import request, flash, redirect, current_app
 3from werkzeug.utils import secure_filename
 4
 5ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "gif", "pdf"}
 6
 7def allowed_file(filename):
 8    return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
 9
10@bp.route("/upload", methods=["POST"])
11def upload():
12    if "upload_file" not in request.files:
13        flash("ファイルが選択されていません。")
14        return redirect(request.url)
15
16    file = request.files["upload_file"]
17
18    if file.filename == "":
19        flash("ファイル名が空です。")
20        return redirect(request.url)
21
22    if file and allowed_file(file.filename):
23        filename = secure_filename(file.filename)
24        save_path = os.path.join(current_app.config["UPLOAD_FOLDER"], filename)
25        file.save(save_path)
26        flash("ファイルのアップロードに成功しました。")
27        return redirect(request.url)
28
29    flash("許可されていないファイル形式です。")
30    return redirect(request.url)

3. セキュリティ上の考慮点
#

  • ファイル名の上書き・ディレクトリトラバーサル防止: 必ず werkzeug.utils.secure_filename を通す。
  • 最大容量の制限: MAX_CONTENT_LENGTH を設定して巨大ファイルの POST による DoS を防ぐ(例: app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024)。

ここに掲載する記事はまだありません。