bigywater.tech
Flask · 132

开发模式 Debugger 风险

开发模式的调试器到底暴露了什么?生产环境会不会误开?用 gunicorn 部署还有调试器吗?这篇用真实的 flask run 与 gunicorn 对比同一个出错的页面,并检查几种开关的优先关系(只看页面里有什么,没有尝试使用控制台)。

7 项
调试页面里检查的信息项,debug 开启时 6 项出现,关闭时 0 项
127.0.0.1
调试服务器默认监听的地址
--debug 优先
FLASK_DEBUG=0 加 --debug 仍然开启调试器

调试页面里有什么

实测 · 本机执行输出
  状态码 500
    含 "Werkzeug Debugger"              True
    含源码行 "return 1 / 0"                True
    含文件路径 app.py                       True
    含异常类型 ZeroDivisionError            True
    含 console 脚本(交互式控制台)               True
    含局部变量值 s3cret                      True
    含 SECRET_KEY 的值                    False
  服务器启动日志里的提示: ['* Debug mode: on']

上一篇:登录失败锁定;下一篇:安全响应头。

关闭 debug

实测 · 本机执行输出
  状态码 500 | 响应: <!doctype html> <html lang=en> <title>500 Internal Server Error</title> <h1>Internal Server Error</h1> <p>The 
    含 "Werkzeug Debugger"              False
    含源码行 "return 1 / 0"                False
    含文件路径 app.py                       False
    含异常类型 ZeroDivisionError            False
    含 console 脚本(交互式控制台)               False
    含局部变量值 s3cret                      False
    含 SECRET_KEY 的值                    False

gunicorn

实测 · 本机执行输出
  状态码 500 | 响应: <html>   <head>     <title>Internal Server Error</title>   </head>   <body>     <h1><p>Internal Server Error</
  含调试器页面: False
  gunicorn 日志里记录了异常(堆栈在服务端日志里,不在响应里): True

监听地址

实测 · 本机执行输出
  默认               → ['* Running on http://127.0.0.1:9604']
  --host 0.0.0.0   → ['* Running on all addresses (0.0.0.0)', '* Running on http://127.0.0.1:9605']

开关的优先关系

实测 · 本机执行输出
  flask run(无参数)                     → 调试器页面: False
  flask run --debug                  → 调试器页面: True
  FLASK_DEBUG=1 flask run            → 调试器页面: True
  FLASK_DEBUG=0 flask run --debug    → 调试器页面: True

调试器的 PIN 保护与交互式控制台本篇没有验证,也没有尝试使用控制台。

分步演示

开发模式 Debugger 风险
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。flask run 与 gunicorn
    • 没有验证:调试器 PIN 的生成与保护强度、WERKZEUG_DEBUG_PIN 与 use_evalex 的作用、uwsgi 与其它服务器、反向代理后面调试页面的可达性、Docker 里 host 绑定的常见误配
    京ICP备2026067502号-1京公网安备11010502063487号