Flask 安全

Web 应用安全需要从配置、输入校验、认证授权、会话管理和部署环境多方面同时考虑。本章介绍 Flask 项目中最常见的安全实践。

关闭生产调试模式

生产环境绝不能启用 debug=True。调试模式可能暴露错误详情,甚至带来远程执行风险。

if __name__ == "__main__":
    app.run(debug=False)

更推荐通过环境区分配置:

class ProductionConfig:
    DEBUG = False
    TESTING = False

保护密钥

SECRET_KEY 用于签名 Cookie 和 CSRF Token,不应写死在代码仓库中。

import os

app.config["SECRET_KEY"] = os.environ["SECRET_KEY"]

如果应用使用会话 Cookie,建议开启以下配置:

app.config.update(
    SESSION_COOKIE_HTTPONLY=True,
    SESSION_COOKIE_SECURE=True,
    SESSION_COOKIE_SAMESITE="Lax",
)
  • HTTPONLY 防止 JavaScript 读取 Cookie
  • SECURE 要求 Cookie 只通过 HTTPS 发送
  • SAMESITE 降低跨站请求风险

输入校验

不要信任客户端传入的数据。对 JSON、表单、路径参数都应做类型、长度和格式校验。

@app.post("/users")
def create_user():
    data = request.get_json() or {}
    email = data.get("email", "").strip()

    if "@" not in email:
        return {"message": "invalid email"}, 400

    return {"email": email}, 201

防止 SQL 注入

不要拼接 SQL 字符串。使用 ORM 或参数化查询。

# 推荐:参数化查询
cursor.execute("SELECT * FROM users WHERE email = ?", (email,))

CSRF 防护

如果项目使用表单和 Cookie 登录,应启用 CSRF 防护。使用 Flask-WTF 时可以这样配置:

from flask_wtf.csrf import CSRFProtect

csrf = CSRFProtect()
csrf.init_app(app)

权限控制

认证只回答“你是谁”,授权回答“你能做什么”。不要只在前端隐藏按钮,后端接口也必须检查权限。

def require_admin(user):
    if not user.is_admin:
        abort(403)

安全响应头

可以通过扩展或中间件设置安全响应头,例如:

  • Content-Security-Policy
  • X-Content-Type-Options
  • Referrer-Policy
  • Strict-Transport-Security

小结

Flask 安全的重点是:生产环境关闭调试、保护密钥、启用 HTTPS 和安全 Cookie、校验输入、避免 SQL 注入,并在后端执行权限检查。安全不是单个配置项,而是一组持续执行的工程习惯。