Files
FastapiAdmin/backend/env/.env.example
T
zhangtao 07fa789d2e fix(backend): 安全默认值、异常语义、代码生成注入面与定时任务内置处理器
本批为 t10 → t13 → t15 三轮实现 + 一轮复核驳回整改的最终形态(pytest 83 passed / ruff clean,
已部署并线上验证)。

异常语义
- CustomException 默认状态码 500 → 400(约 433 处裸调用不再被计为服务端故障),
  且「包装底层异常」的 130 处显式恢复 500;get_or_404 → 404;响应体结构不变

代码生成注入面(复核 blocker F1,二次修复)
- column_type 不再做字符串拼接:改为常量白名单派生(类型名 ∈ DB_TO_SQLALCHEMY ∪ {Boolean},
  长度仅取数字/正则捕获),彻底移除 split("(")[1]
- 列类型加形状白名单;字符串/注释/文档字符串用 \uXXXX,标识符过 safe_ident(含 Python/JS 关键字),
  .vue 文本与静态属性改 HTML 实体
- 落盘闸门由 ast.parse 升级为 assert_python_structure(语法 + 顶层语句白名单 + 与哨兵骨架逐节点比对)
  与 assert_text_structure(.vue/.ts/.toml 行结构);U+2028/2029 与 C1 控制符纳入转义

安全默认值
- 生产 CORS 不再回落 ["*"](未配置即拒绝跨域,可选 CORS_STRICT_STARTUP 直接启动失败)
- OAUTH_ALLOWED_HOSTS 不再默认 "*";新增 ALLOW_LOCALHOST_HOSTS 控制 Host 校验范围
- ALLOWED_HOSTS 收窄为按配置派生;健康检查暴露 code_exec_enabled / cors_origins_configured

定时任务
- SCHEDULER_ALLOW_CODE_EXEC 默认 False;新增 builtin:<模块名>[.<函数名>] 内置处理器路线(不经 exec)
- 判定收敛到 describe_schedulability;列表返回 schedulable / unschedulable_reason;
  启动 reconcile 与状态查询对「已启用但不可调度」打 WARN(去重、恢复后清除)
- 加固:内置处理器必须在本模块内定义或经 HANDLERS 声明,拒绝模块内导入的外部对象(复核 R1)
- 顺带修复:_WARNED_UNSCHEDULABLE 的 set.pop TypeError、job.next_run_time 缺失导致的列表 500

测试:新增 tests/test_generator_template_safety.py、test_security_defaults.py、
test_scheduler_schedulability.py(含恶意载荷、闸门红绿、静态护栏)
2026-10-04 05:12:32 +08:00

101 lines
5.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ==================================
# 环境配置文件:修改名称example为.env.dev或.env.prod 修改内容:ENVIRONMENT、SECRET_KEY、DATABASE_PASSWORD、REDIS_PASSWORD、OPENAI_API_KEY
# ==================================
ENVIRONMENT = dev # prod
# 服务器配置
SERVER_HOST = localhost
SERVER_PORT = 8001
# 前置可信反向代理跳数:docker 部署默认单层 nginx(默认 1);后端直接暴露公网时填 0,防止 X-Forwarded-For 伪造
# TRUSTED_PROXY_HOPS = 1
# 文档配置
DEBUG = True
VERSION = 3.1.0
# 是否启用演示模式
DEMO_ENABLE = False
# 数据库配置:mysql-3306、postgres-5432、sqlite
DATABASE_TYPE = mysql
DATABASE_HOST = localhost
DATABASE_PORT = 3306
DATABASE_USER = root
DATABASE_PASSWORD = your_database_password
DATABASE_NAME = fastapiadmin
# Redis配置
REDIS_HOST = localhost
REDIS_PORT = 6379
REDIS_USER = ''
REDIS_PASSWORD = your_redis_password
REDIS_DB_NAME = 1
# 日志级别配置
LOGGER_LEVEL = DEBUG
# ================================================= #
# *************** 安全相关(生产必填)*************** #
# ================================================= #
# 令牌签名密钥:openssl rand -hex 32(更换后所有已签发令牌失效)
SECRET_KEY = change_me_generate_with_openssl_rand_hex_32
# 落库敏感数据加密主密钥:openssl rand -hex 32;留空则由 SECRET_KEY 派生
DATA_ENCRYPTION_KEY = ''
# 轮换前的旧主密钥(逗号分隔),仅用于解密历史密文
DATA_ENCRYPTION_OLD_KEYS = ''
# 生产跨域白名单(逗号分隔,如 https://admin.example.com,https://www.example.com)
# ⚠️ 生产留空 = 拒绝全部跨域请求(安全默认,不再回落通配 "*";同源部署不受影响)。
# 存在站外集成时必须显式列出域名;填 "*" 会被忽略(与 ALLOW_CREDENTIALS=True 组合不可接受)。
PROD_CORS_ORIGINS = ''
# 严格启动:true 时「生产未配置 PROD_CORS_ORIGINS」直接启动失败(默认 false 只打 warning)
CORS_STRICT_STARTUP = False
# 只信任该网段内的反向代理传来的 X-Forwarded-*(切勿使用 *)
FORWARDED_ALLOW_IPS = 10.255.178.0/24
# 演示模式:true 时禁止写操作
DEMO_ENABLE = False
# ================================================= #
# ******************* 定时任务 ******************* #
# ================================================= #
# 是否允许定时任务执行用户提交的代码块(exec,等同服务器代码执行权限)。
# ⚠️ 默认 False:调成 false(或保持默认)时,**所有「代码块型」节点任务都不会被调度**
# (注册/手动执行会返回明确错误:"服务已禁用定时任务代码执行…"),执行结果可在任务执行日志查看;
# 这只关闭 exec 能力,不影响调度器本身、也不影响无代码块的其它任务。
# 如确需该能力,请显式置为 true,并按最小权限授予任务管理权限。
SCHEDULER_ALLOW_CODE_EXEC = False
# ================================================= #
# ******************* 主机名校验 ******************* #
# ================================================= #
# 允许的 Host 头(逗号分隔的 JSON 数组);生产填真实域名
# ALLOWED_HOSTS = ["service.fastapiadmin.com", "*.fastapiadmin.com"]
# 容器内健康检查/本地直连需要 Host: localhost|127.0.0.1|[::1];生产不需要时置 False 收敛校验范围
ALLOW_LOCALHOST_HOSTS = True
# OAuth 回调域名白名单(**不再是通配符 "*"**);非生产默认额外放行本机与回环地址
# OAUTH_ALLOWED_HOSTS = ["service.fastapiadmin.com", "*.fastapiadmin.com", "localhost", "127.0.0.1", "[::1]"]
# 大模型配置
OPENAI_BASE_URL = https://api.deepseek.com
OPENAI_API_KEY = your_api_key
OPENAI_MODEL = deepseek-v4-flash
# ================================================= #
# *********** 升级说明(行为变更,请逐条确认)***********
# ================================================= #
# 1) SCHEDULER_ALLOW_CODE_EXEC 默认由 true 改为 false:升级后所有「代码块型」节点任务
# 不再被调度/执行,直至显式配置为 true。健康检查(/api/v1/monitor/health/check)新增
# code_exec_enabled 字段可用于确认当前生效值。
# 2) 生产 PROD_CORS_ORIGINS 未配置时不再回落通配 "*",而是拒绝全部跨域请求
# (同源部署不受影响)。健康检查新增 cors_origins_configured 字段;可用 CORS_STRICT_STARTUP=true
# 把它变成启动失败以便尽早发现。
# 3) 业务异常的 HTTP 状态码按语义返回:客户端可修正类为 4xx(参数/验证码 400、无权限 403、
# 资源不存在 404),包装底层异常的内部故障为 500(此前统一 500/后统一 400 均不正确)。
# 4) 代码生成器的列名必须是合法标识符(且不能是 Python 关键字 / JS 保留字),
# 列类型必须是「类型名 + 可选(长度[,精度]) + 可选[] + 可选 unsigned」的形状;
# 含引号/分号/任意自由文本的类型会被拒绝(ENUM/SET 会归一化为基名)。
# 5) 代码生成落盘前新增结构闸门:.py 产物必须与「哨兵值骨架」AST 一致,.vue/.ts/.toml 做行结构比对,
# 任何注入/转义缺口都会在写盘前报错,而不是写出可被启动期 import 的坏文件。
# 6) OAUTH_ALLOWED_HOSTS 默认不再是 "*";如需自定义请在对应环境中显式配置。
# 7) ALLOWED_HOSTS 默认不再无条件包含 localhost:由 ALLOW_LOCALHOST_HOSTS 控制(默认 True 以兼容容器健康检查)。