记录 Flask 文件上传中,常用的大小限制与路径校验方法。


一、限制文件大小

Flask 提供了 MAX_CONTENT_LENGTH 配置,超出限制会自动返回 413 错误。

from flask import Flask

app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024  # 限制 5MB

也可在保存前手动判断文件大小:

file = request.files['file']
file.seek(0, 2)  # 移动到末尾
size = file.tell()
file.seek(0)     # 回到开头

if size > 5 * 1024 * 1024:
    return jsonify({'error': '文件过大'}), 400

二、路径安全校验

上传文件时需防止路径穿越漏洞(如 ../../etc/passwd)。

from werkzeug.utils import secure_filename
import os

UPLOAD_FOLDER = './uploads'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

filename = secure_filename(file.filename)  # 去除危险字符
save_path = os.path.join(UPLOAD_FOLDER, filename)

# 确保路径在 UPLOAD_FOLDER 内
if not os.path.abspath(save_path).startswith(os.path.abspath(UPLOAD_FOLDER)):
    return jsonify({'error': '非法文件路径'}), 400

三、综合示例

@app.route('/upload', methods=['POST'])
def upload_file():
    file = request.files.get('file')
    if not file:
        return jsonify({'error': '未选择文件'}), 400

    filename = secure_filename(file.filename)
    save_path = os.path.join(UPLOAD_FOLDER, filename)

    if not os.path.abspath(save_path).startswith(os.path.abspath(UPLOAD_FOLDER)):
        return jsonify({'error': '非法路径'}), 400

    file.seek(0, 2)
    size = file.tell()
    file.seek(0)
    if size > 5 * 1024 * 1024:
        return jsonify({'error': '文件过大'}), 400

    file.save(save_path)
    return jsonify({'message': '上传成功'})

四、小结

  • 大小限制:可用 MAX_CONTENT_LENGTH 或手动判断
  • 路径校验:必须结合 secure_filename 与绝对路径验证
  • 安全防护:防止路径穿越与大文件导致的服务阻塞