Internal exception messages leak to API response via InternalServerError(str(e))

当 Dify 的 Console API 在处理请求时抛出未预期异常,代码会把原始 Python 异常字符串通过 InternalServerError(str(e)) 写入响应体,导致内部错误细节暴露给调用方。优先排查 message.py、external.py、hit_testing_base

快速结论:当 Dify 的 Console API 在处理请求时抛出未预期异常,代码会把原始 Python 异常字符串通过 InternalServerError(str(e)) 写入响应体,导致内部错误细节暴露给调用方。优先排查 message.py、external.py、hit_testing_base.py 三处 catch-all 处理分支,以及 Console API 通用错误处理器是否会透传 description。

适用环境:Issue 已确认:Dify 1.17.1,Self Hosted (Docker)。其他操作系统、Python、CUDA、显卡与依赖版本未在 Issue 中给出。

最快修复方案:暂无确认的一步修复方案。Issue 中仅给出预期修复示例:保留 logger.exception 记录完整异常,把响应体改为通用错误文案(如 “An internal error occurred” / “Internal server error”),而不是 str(e)。Issue 讨论中未提供已验证的补丁或发布版本。

注意事项:该方案会减少客户端可读的错误细节,前端若依赖具体错误文案做提示可能需要同步调整;issue 评论尚未确认维护者是否希望改为在通用异常处理 handle_general_exception 中集中处理,直接逐点修改可能与后续实现冲突;external.py 分支缺少 logger.exception,修改时应同时保证服务端仍有完整异常日志。

问题场景

在 Dify Web 控制台创建任意 Chatflow 应用后,调用反馈导出接口并传入非法日期参数,例如 GET /console/api/apps/<app_id>/feedbacks/export?format=csv&from_source=user&start_date=not-a-date,响应中出现原始 Python 异常字符串。同类写法还出现在数据集外部知识命中测试接口,以及 Console 非外部命中测试的公共基类中。

报错原文

Internal exception messages leak to API response via InternalServerError(str(e))

{"error":"Parameter validation error: Invalid start_date format: not-a-date. Use YYYY-MM-DD"}

raise InternalServerError(str(e))

原因分析

问题在于异常处理把 str(e) 直接传给了 InternalServerError。该构造会把原始异常信息设置为异常的 description,而 Console API 的通用 Flask-RESTX 错误处理器会把 description 原样复制进 JSON 响应体,链路下游没有再做脱敏。可能原因包括:call site 的 catch-all 分支写法统一复用了 str(e);外部知识命中测试分支甚至没有 logger.exception,异常既出现在响应中、也可能缺少服务端日志。触发源可能是参数校验失败(如 start_date 格式错误),也可能是数据库错误、连接错误、导入错误等任意未处理异常。

环境排查

  • 确认 Dify 版本与部署方式(Issue 为 1.17.1 / Self Hosted Docker),升级或切换版本后再复现,确认问题是否随版本变化。
  • 确认复现路径:Console 反馈导出接口、数据集外部知识命中测试接口、Console 命中测试接口是否都受影响。
  • 检查 api/controllers/console/app/message.py 中是否有 logger.exception 后紧跟 raise InternalServerError(str(e))。
  • 检查 api/controllers/console/datasets/external.py 的 except 分支是否只有 raise InternalServerError(str(e)) 而无日志。
  • 检查 api/controllers/console/datasets/hit_testing_base.py 中 perform_hit_testing 是否同时存在 str(e) 包装的 InternalServerError 与 ValueError。
  • 检查 Console 通用错误处理是否把异常 description 写入响应,确认是否存在集中脱敏逻辑。

解决步骤

  1. 先稳定复现:用非法 start_date 调用反馈导出接口,记录 HTTP 状态码与响应体中的异常文案。
  2. 定位三处分支:message.py 的 MessageFeedbackExportApi.get、external.py 的 ExternalKnowledgeHitTestingApi.post、hit_testing_base.py 的 DatasetsHitTestingBase.perform_hit_testing。
  3. 可优先尝试按 Issue 示例修改:保留 logger.exception(“…”) 记录完整堆栈,再把 InternalServerError(str(e)) 改为固定通用文案;参数校验分支如仍需要提示格式,仅保留受控的格式说明,不回显原始异常。
  4. 对 external.py 分支补充 logger.exception,确保服务端日志不因脱敏而丢失异常信息。
  5. 如团队倾向集中处理,可在 handle_general_exception(libs/external_api.py)统一屏蔽 description 透传;该方向 issue 中尚未确认,修改前先与维护者对齐,避免与逐点修复重复或冲突。
  6. 参考 PR #41102、PR #42177 中在 trigger/webhook.py 与 MCP connect/auth 500 响应上的同类处理方式,保持文案与日志风格一致。

验证方法

以非法 start_date 及可构造异常的条件再次调用反馈导出接口,确认响应体只包含通用错误文案、不再出现原始 Python 异常;同时查看服务端日志仍记录完整异常堆栈。对数据集外部命中测试与 Console 命中测试做同样验证。若触发真实内部错误(如依赖不可用),确认返回 500 且不泄露内部信息。

参考来源

langgenius/dify #43046
langgenius/dify PR #41102
langgenius/dify PR #42177

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 29431

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注