ファイルアップロードとバリデーション
概要#
Web フォームから送信されたファイルの安全な受信・保存処理。ファイル名のサニタイズ(secure_filename)、拡張子バリデーション、アップロード容量制限についてのまとめ。
参考ブログ記事#
1. HTML フォーム側の設定#
ファイルをアップロードする場合、form タグに enctype="multipart/form-data" を必ず指定する。
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)。
ここに掲載する記事はまだありません。
