You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python Flask禁止指定目录下的脚本执行

上传脚本目录执行权限限制方案(Flask + Python 3实现)

核心防护逻辑

需要结合操作系统权限管控和Flask应用层校验两层防护,避免单一层面被绕过导致脚本被执行。


1. 操作系统层面基础权限配置

先从底层限制上传目录下所有文件的执行权限,Linux环境下直接执行如下命令:

# 替换为你实际的上传目录路径
UPLOAD_DIR="/opt/app/user_upload_scripts"

# 所有子目录设置为755权限(仅所有者可修改,其余用户仅可进入读取)
find $UPLOAD_DIR -type d -exec chmod 755 {} \;
# 所有普通文件设置为644权限,完全移除所有执行位
find $UPLOAD_DIR -type f -exec chmod 644 {} \;
# 目录所属用户修改为Flask进程的运行用户,禁止其他用户修改权限
chown -R flask_run_user:flask_run_group $UPLOAD_DIR

注意:禁止给上传目录下的任何普通文件设置x执行位,哪怕是Flask进程所有者的执行权限也不需要开启。


2. Flask应用层上传时权限管控

所有文件上传落盘时直接指定权限,避免操作系统默认权限带执行位,示例代码如下:

import os
from flask import Flask, request, abort

app = Flask(__name__)
# 上传目录不要放在Flask的static、templates等默认路由可访问的目录下
app.config["UPLOAD_FOLDER"] = "/opt/app/user_upload_scripts"
# 按需配置允许的文件后缀,建议不要加入py、js、sh、php等可执行脚本后缀
ALLOWED_EXTENSIONS = {"txt", "json", "csv", "md"}

def check_file_ext(filename: str) -> bool:
    return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route("/script/upload", methods=["POST"])
def upload_script():
    if "upload_file" not in request.files:
        abort(400, description="未上传文件")
    file = request.files["upload_file"]
    if file.filename == "":
        abort(400, description="文件名为空")
    if not check_file_ext(file.filename):
        abort(400, description="不允许的文件类型")
    
    # 建议对上传文件重命名,去掉原始可执行后缀,比如将xxx.py改为xxx_py.txt,避免被解析为可执行文件
    save_filename = os.path.basename(file.filename).replace(".", "_") + ".txt"
    save_path = os.path.join(app.config["UPLOAD_FOLDER"], save_filename)
    file.save(save_path)
    # 落盘后立刻修改文件权限,移除执行位
    os.chmod(save_path, 0o644)
    return "文件上传成功", 200

3. 后续防护加固

  • 不要使用send_from_directory等Flask内置方法直接返回上传目录下的文件,避免服务端自动解析执行脚本文件,所有文件读取需求都通过接口读取文件内容后返回。
  • 可添加定时任务定期重置上传目录权限,防止遗漏的可执行权限残留,可通过APScheduler实现定时扫描:
from apscheduler.schedulers.background import BackgroundScheduler

def reset_upload_permission():
    upload_dir = app.config["UPLOAD_FOLDER"]
    for root, dirs, files in os.walk(upload_dir):
        # 重置目录权限
        for d in dirs:
            os.chmod(os.path.join(root, d), 0o755)
        # 重置所有普通文件权限
        for f in files:
            os.chmod(os.path.join(root, f), 0o644)

# 服务启动时开启定时任务,每小时扫描一次
scheduler = BackgroundScheduler()
scheduler.add_job(reset_upload_permission, "cron", hour="*")
scheduler.start()

内容的提问来源于stack exchange,提问作者user16421569

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 20:45:03