线上一个空指针,接口返回的 JSON 里 debug 字段是完整堆栈,最后一行带着 postgresql://app:Passw0rd@10.0.3.7:5432/order。前端把这个结构直接渲染在了提示框里。日志里能对上时间点,这种反而好排。

debug 开关跟着代码一起发到了生产,框架就把异常详情序列化进响应。堆栈里有文件路径、SQL、连接串,这些都是攻击者最想要的信息。开发环境的默认值被原样带上了线。这一点先确认清楚,后面就不用反复试。

app.config['DEBUG'] = os.getenv('APP_ENV') == 'dev'
@app.errorhandler(Exception)
def on_err(e):
    return {'code': 500, 'trace_id': g.trace_id}, 500

「错误堆栈外泄」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。

处理上按这个顺序:生产环境关掉 debug 统一返回错误码和 trace id;异常在中间件里捕获 详细信息只写服务端日志;配置用环境变量区分 启动时打印当前模式;全局搜 debug=True 和 app.run(debug 这类写法。

结果对不对很好判断,手动触发一个异常 响应里只有错误码和 trace id 完整堆栈能在日志里按 id 搜到。

作者 9823189